实现生产者消费者模式
我正在尝试编写一个邮件实用程序,将邮件放入队列中,然后由消费者线程使用。
我正在尝试实现典型的生产者-消费者模式,但出了问题。
我刚刚写了一个骨架,但该骨架没有按预期工作。
MailProducer.java
public class MailProducer implements Callable<Void>
{
@Override
public Void call() throws Exception
{
System.out.println("inside mail Producer");
System.out.println("Thread executing = " +
Thread.currentThread().getName());
return null;
}
}
MailConsumer.java
public class MailConsumer implements Callable<Void>
{
@Override
public Void call() throws Exception
{
System.out.println("inside mail consumer");
System.out.println("Thread executing = " +
Thread.currentThread().getName());
return null;
}
}
以及最后的执行器
MailExecutor.java
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
I am trying to write a mail utility that places mails in a queue, and it is later consumed by a consumer thread.
I am trying to implement a typical producer-consumer pattern, but something is going wrong.
I just wrote a skeleton , and the skeleton is not working as expected.
MailProducer.java
public class MailProducer implements Callable<Void>
{
@Override
public Void call() throws Exception
{
System.out.println("inside mail Producer");
System.out.println("Thread executing = " +
Thread.currentThread().getName());
return null;
}
}
MailConsumer.java
public class MailConsumer implements Callable<Void>
{
@Override
public Void call() throws Exception
{
System.out.println("inside mail consumer");
System.out.println("Thread executing = " +
Thread.currentThread().getName());
return null;
}
}
and finally the Executor
MailExecutor.java
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");
}
}
Now when I run the program, I expect it to go back and forth the producer and consumer to keep printing what is written in the respective classes. But instead , the program hangs/does nothing after printing the below lines . What is going wrong ? Am I missing something?
Output ...(Output is not what I had expected. What is going wrong ?)
inside mail consumer
inside main
Thread executing = pool-1-thread-1
inside mail Producer
Thread executing = pool-1-thread-2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您缺少共享队列。没有队列,你就一无所有。
生产者将工作放入队列中。消费者将工作从队列中移除。使用
BlockingQueue
< /a>,其put()
和take()
方法是阻塞调用。在单独的线程中运行生产者和消费者允许他们在调用这些方法时安全地阻塞。生产者和消费者都不需要
可调用
;Runnable
就可以了。使用执行器
< /a> 将它们结合在一起是个好主意。You are missing the shared queue. Without the queue, you have nothing.
Producers put work onto the queue. Consumers take work off the queue. Use a
BlockingQueue
, whoseput()
andtake()
methods are blocking calls. Running producers and consumers in separate threads allows them to safely block while calling these methods.Neither the producers nor the consumers need to be
Callable
;Runnable
will do. Using anExecutor
to tie it all together is a good idea.ExecutorService.submit 安排一个 Runnable 或 Callable 执行一次。您的输出显示 MailProducer 和 MailConsumer 均执行一次,因此一切正常。
您应该将 Producer 和 Consumer 方法的内部放置在循环中:
这会给出您期望的输出。
ExecutorService.submit schedules a Runnable or Callable for one execution. Your output shows that MailProducer and MailConsumer both executed once, so everything works like it should.
You should place the inside of your Producer and Consumer methods in loops:
This gives the output you expect.
您必须使用循环,以便您的生产者/消费者代码执行多次。
您的线程之间不进行通信。目前您只有两个线程正在执行。查看 BlockingQueue 中的示例 如何执行此操作的 javadoc。
You must use loops so that your producer/consumer code is executed more than once.
Your threads do not communicate with each other. Currently you have only two threads being executed. Look at the example in the BlockingQueue javadoc of how to do it.