Java 实施生产者-消费者模式

Java 实施生产者-消费者模式,java,multithreading,concurrency,producer-consumer,executor,Java,Multithreading,Concurrency,Producer Consumer,Executor,我正在尝试编写一个邮件实用程序,将邮件放入队列中,然后由消费者线程使用 我试图实现一个典型的生产者-消费者模式,但有些地方出了问题 我刚刚写了一个骨架,骨架没有按预期工作 MailProducer.java 现在,当我运行这个程序时,我希望它能够来回地由生产者和消费者来打印在各自的类中编写的内容。但是,在打印以下行后,程序将挂起/不执行任何操作。出什么事了?我错过什么了吗 输出…输出不是我所期望的。出什么事了 inside mail consumer inside main T

我正在尝试编写一个邮件实用程序,将邮件放入队列中,然后由消费者线程使用

我试图实现一个典型的生产者-消费者模式,但有些地方出了问题

我刚刚写了一个骨架,骨架没有按预期工作

MailProducer.java

现在,当我运行这个程序时,我希望它能够来回地由生产者和消费者来打印在各自的类中编写的内容。但是,在打印以下行后,程序将挂起/不执行任何操作。出什么事了?我错过什么了吗

输出…输出不是我所期望的。出什么事了

   inside mail consumer
   inside main
   Thread executing = pool-1-thread-1
   inside mail Producer
   Thread executing = pool-1-thread-2

ExecutorService.submit为一次执行安排可运行或可调用的。您的输出显示MailProducer和MailConsumer都执行了一次,所以一切正常

您应该将生产者和消费者方法的内部放入循环中:

import java.util.concurrent.*;

public class Executor {

    private static final int NTHREADS = 25;
    private static final ExecutorService exec = 
        Executors.newFixedThreadPool(NTHREADS);


    public static void main(String[] args) {
        exec.submit(new MailConsumer());
        exec.submit(new MailProducer());

        System.out.println("inside main");  
    }


    static class MailProducer implements Runnable {
        @Override
        public void run() {
            while (true) {
                System.out.println("inside mail Producer");
                System.out.println("Thread executing = " +
                       Thread.currentThread().getName());
            }
       }
    }

    static class MailConsumer implements Runnable {
        @Override
        public void run() {
            while (true) {
                System.out.println("inside mail Consumer");
                System.out.println("Thread executing = " +
                       Thread.currentThread().getName());
            }
       }
    }
}

这将提供您期望的输出。

您缺少共享队列。没有队列,你什么都没有

制作人把作品排在队列中。消费者不再排队工作。使用,其和方法阻止调用。在单独的线程中运行生产者和消费者允许他们在调用这些方法时安全地阻塞

生产商和消费者都不需要这样做;Runnable就行了。使用一个简单的方法将其全部绑定在一起是一个好主意

您必须使用循环,以便生产者/消费者代码被多次执行

线程之间不通信。目前只有两个线程正在执行。请看javadoc中的示例,了解如何执行此操作


虽然你的答案解决了一个重要问题,但你没有抓住要点:使用BlockingQueue或类似的东西。是的,但原始海报的代码也是如此——他将其描述为一个框架,因此我认为他试图先让线程池工作,然后再实现Producent Consumer。是的,但这将使用两个线程,而且也不需要执行者。没什么大不了的,但是阻塞方法实际上是放在一起的。如果没有空格,报价将返回false。
  public class MailExecutor
  {

private static final int NTHREADS = 25;
private static final ExecutorService exec = 
                Executors.newFixedThreadPool(NTHREADS);

public static void main(String[] args)
{
    exec.submit(new MailConsumer());
    exec.submit(new MailProducer());

    System.out.println("inside main");

}

  }
   inside mail consumer
   inside main
   Thread executing = pool-1-thread-1
   inside mail Producer
   Thread executing = pool-1-thread-2
import java.util.concurrent.*;

public class Executor {

    private static final int NTHREADS = 25;
    private static final ExecutorService exec = 
        Executors.newFixedThreadPool(NTHREADS);


    public static void main(String[] args) {
        exec.submit(new MailConsumer());
        exec.submit(new MailProducer());

        System.out.println("inside main");  
    }


    static class MailProducer implements Runnable {
        @Override
        public void run() {
            while (true) {
                System.out.println("inside mail Producer");
                System.out.println("Thread executing = " +
                       Thread.currentThread().getName());
            }
       }
    }

    static class MailConsumer implements Runnable {
        @Override
        public void run() {
            while (true) {
                System.out.println("inside mail Consumer");
                System.out.println("Thread executing = " +
                       Thread.currentThread().getName());
            }
       }
    }
}