3

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

我正在尝试实现一个典型的生产者-消费者模式,但是出了点问题。

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

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;
}

}

邮件消费者.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
4

3 回答 3

2

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

生产者将工作放入队列中。消费者将工作从队列中移除。使用 a BlockingQueue,其put()take()方法是阻塞调用。在不同的线程中运行生产者和消费者允许他们在调用这些方法时安全地阻塞。

生产者和消费者都不需要CallableRunnable会做。使用 anExecutor将它们捆绑在一起是个好主意。

于 2011-10-24T12:09:50.757 回答
1

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());
            }
       }
    }
}

这给出了您期望的输出。

于 2011-10-24T11:54:48.807 回答
0
  1. 您必须使用循环,以便您的生产者/消费者代码多次执行。

  2. 您的线程不相互通信。目前您只有两个线程正在执行。查看BlockingQueue javadoc 中的示例以了解如何执行此操作。

于 2011-10-24T12:10:44.313 回答