3

メールをキューに入れるメール ユーティリティを作成しようとしていますが、後でコンシューマ スレッドによって消費されます。

典型的な生産者と消費者のパターンを実装しようとしていますが、何かがうまくいきません。

スケルトンを書きましたが、スケルトンが期待どおりに動作しません。

メールプロデューサー.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
4

3 に答える 3

2

共有キューがありません。キューがなければ、何もありません。

プロデューサーは作業をキューに入れます。コンシューマはキューから作業を取り除きます。とメソッドが呼び出しをブロックBlockingQueueしているを使用します。プロデューサとコンシューマを別々のスレッドで実行すると、これらのメソッドの呼び出し中に安全にブロックできます。put()take()

生産者も消費者もそうである必要はありませんCallableRunnableしましょう。を使用しExecutorてすべてを結び付けることをお勧めします。

于 2011-10-24T12:09:50.757 に答える
1

ExecutorService.submitは、1回の実行に対してRunnableまたはCallableをスケジュールします。出力は、MailProducerとMailConsumerの両方が1回実行されたことを示しているため、すべてが正常に機能します。

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. あなたのスレッドは互いに通信しません。現在、実行中のスレッドは 2 つだけです。その方法については、 BlockingQueue javadoc の例を参照してください。

于 2011-10-24T12:10:44.313 に答える