我正在尝试编写一个邮件实用程序,将邮件放在队列中,然后由消费者线程使用 .
我正在尝试实现典型的 生产环境 者 - 消费者模式,但出现了问题 .
我刚刚写了一个骨架,骨架没有按预期工作 .
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");
}
}
现在,当我运行程序时, I expect it to go back and forth the producer and consumer to keep printing what is written in the respective classes . 但相反,程序在打印下面的行后会挂起/不执行任何操作 . 出了什么问题?我错过了什么吗?
Output ...(输出不是我的预期 . 出了什么问题?)
inside mail consumer
inside main
Thread executing = pool-1-thread-1
inside mail Producer
Thread executing = pool-1-thread-2
3 回答
您缺少共享队列 . 没有队列,你什么都没有 .
制片人把工作放到队列中 . 消费者将工作排除在外 . 使用BlockingQueue,其put()和take()方法阻止调用 . 在单独的线程中运行 生产环境 者和使用者允许他们在调用这些方法时安全地阻塞 .
生产环境 者和消费者都不需要Callable;
Runnable
会的 . 使用Executor将它们绑在一起是一个好主意 .ExecutorService.submit为一次执行调度Runnable或Callable . 您的输出显示MailProducer和MailConsumer都执行了一次,所以一切都像它应该的那样 .
您应该将Producer和Consumer方法的内部放在循环中:
这给出了您期望的输出 .
您必须使用循环,以便多次执行 生产环境 者/消费者代码 .
您的线程不相互通信 . 目前,您只有两个线程正在执行 . 查看BlockingQueue javadoc中的示例,了解如何执行此操作 .