質問

SynchronousQueueを持つ1つのスレッドから要素を挿入するput()が欲しいので、要素が別のスレッドに取り込まれるまで入力がブロックされます。

他のスレッドでは多くの計算を実行しますが、時々、要素が既に使用可能かどうかを確認し、それを消費したいと考えています。しかし、別のスレッドがisEmpty()呼び出しで待機している場合でも、<=>は常にtrueを返すようです。

これはどのように可能ですか?サンプルコードは次のとおりです。

@Test
public void testQueue() throws InterruptedException {
    final BlockingQueue<Integer> queue = new SynchronousQueue<Integer>();

    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            while (true) {
                if (!queue.isEmpty()) {
                    try {
                        queue.take();
                        System.out.println("taken!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                // do useful computations here (busy wait)
            }
        }
    });
    t.start();

    queue.put(1234);
    // this point is never reached!
    System.out.println("hello");
}

編集: isEmpty()もpeek()も動作せず、poll()を使用する必要があります。ありがとう!

役に立ちましたか?

解決

からhttp://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/SynchronousQueue.html#put(E)

isEmpty
public boolean isEmpty()
常にtrueを返します。 SynchronousQueueには内部容量がありません。

(これについては詳細に検討していませんが、代わりに poll または take をご覧ください)

他のヒント

Timの答えに加えて、コンシューマスレッドでは何もしていませんが、タイトループでisEmpty()を継続的に呼び出しています。実行するのに役立つ何かがあるまでOSを実行しないように要求するのではなく、コンシューマスレッドは常にビジー状態です。 isEmptyが正しく機能していても、プロデューサースレッドが実行される機会はほとんどありません。

(isEmpty()が機能した場合、またはpoll()の使用に切り替えた場合)プロデューサーに実行の機会を与えるためにキューが空の場合、テスト間で消費者を少しスリープさせるか、または(できれば) isEmpty()テストを実行し、ポーリングの代わりに賢明な方法でtake()内のmutexでスレッドをブロックします。

あなたのコードは、あなたが投票しようとしているように見えます。 poll()メソッドを呼び出すだけではどうですか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top