-2

プロデューサーとコンシューマーのスレッドの問題を調整しようとしています。プロデューサは 10 個のオブジェクトをキューに入れます。つまり、プロデューサーの run メソッドには、10 個のオブジェクトを追加する単純なループが含まれているだけで、終了します。キューがいっぱいになると (キューのサイズは 10)、キューの add メソッドで wait() -> が呼び出されます。コンシューマー側では、コンシューマーはまずオブジェクトを覗いてから、それらを削除し始めます。私が抱えている問題は、プログラムが実行されたときの約 50% のケースで、プロデューサーが 10 個のオブジェクトをキューに置いた後に出力が終了することです。残りの 50% の時間は、プログラムが正常に動作します。つまり、消費者がすべてのオブジェクトを削除します。この問題に対する私の以前の解決策は、プロデューサーの run メソッド内に新しいコンシューマー スレッドを作成することでした。したがって、プロデューサーが 10 個のオブジェクトをキューに入れると、新しいコンシューマー スレッドが作成され、join() を使用して操作を同期しました。ただし、待機と通知を使用してプロセスを機能させたいと考えています。誰かが私が間違っていることを教えてもらえますか? ありがとう

    @Override
    public synchronized boolean add(Process element) {
    if(isFull())
    {
        waitForNotify();
    }

    else
    {          

       queue.add(element);



    }
    return true;
}

    private void invokeNotify() {
    try {
        notify();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

    private void waitForNotify() {
    try {
        wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

     @Override
     public synchronized boolean offer(Process element) throws IllegalStateException {
       queue.add(element);
       this.queue = newHeapSort.heapify(queue, queue.size());
       return true;



}

    @Override
    public synchronized Process peek() {
    if(queue.isEmpty())
    {
        waitForNotify();
    }
    return(queue.get(0));

}

    @Override
    public synchronized Process head() {    
    if(queue.isEmpty()) 
    {
        invokeNotify();
    }

        Process head = queue.get(0);
        queue.remove(0);


        return head;


}
4

1 に答える 1

3

プロデューサはコンシューマ スレッドに通知しません。そのため、コンシューマーが最初に開始した場合、キューが空であることがわかり、永遠に待機します。

私は単純に BlockingQueue を使用します。これがそれを行います。

wait()本当に と を使用したい場合はnotify()、次のことを行う必要があります。

  • 呼び出しの周りにループを使用し、wait()ウェイクアップする条件が真でない場合は待機状態に戻ります
  • プロデューサーがいつ通知するかを決定する (通常、アイテムをキューに入れるとき)
  • コンシューマーがいつ通知するかを決定する (通常、キューからアイテムを削除するとき)
  • コンシューマーがいつ待機するかを決定する (通常、キューが空のとき)
  • プロデューサがいつ待機するかを決定する (通常、キューがいっぱいになったとき)
  • InterruptedException の無視を停止します。それらを伝播させてください。

を使用しますnotifyAll()。これにより、複数のプロデューサーまたはコンシューマーが存在する場合にすべてが正常に機能することも保証されます。

于 2012-11-23T17:35:36.130 に答える