[英]Implementing Producer consumer pattern
我正在尝试编写一个邮件实用程序,将邮件放入队列中,稍后由消费者线程使用。
我正在尝试实现典型的生产者-消费者模式,但出了点问题。
我刚写了一个 skeleton ,这个 skeleton 没有按预期工作。
邮件生产者.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;
}
}
邮件消费者.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;
}
}
最后是执行者
邮件执行器.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
您缺少共享队列。 没有队列,你什么都没有。
生产者将工作放入队列中。 消费者从队列中取出工作。 使用BlockingQueue
,其put()
和take()
方法是阻塞调用。 在单独的线程中运行生产者和消费者允许他们在调用这些方法时安全地阻塞。
生产者和消费者都不需要是Callable
; Runnable
会做。 使用Executor
将它们联系在一起是一个好主意。
ExecutorService.submit 为一次执行安排 Runnable 或 Callable。 您的输出显示 MailProducer 和 MailConsumer 都执行了一次,所以一切正常。
您应该将 Producer 和 Consumer 方法的内部置于循环中:
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());
}
}
}
}
这给出了您期望的输出。
您必须使用循环,以便多次执行您的生产者/消费者代码。
您的线程不相互通信。 目前您只有两个线程正在执行。 查看BlockingQueue javadoc 中的示例,了解如何执行此操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.