0

私には 2 つのスレッドがあり、現在、同期ブロック内でオブジェクトの notify() および wait() メソッドを使用してロックを行っています。メインスレッドがブロックされないようにしたかったので、この方法でブール値を使用しました (関連するコードのみが提供されます)。

//Just to explain an example queue
private Queue<CustomClass> queue = new Queue();

//this is the BOOLEAN
private boolean isRunning = false;

private Object lock;

public void doTask(){
       ExecutorService service = Executors.newCachedThreadPool();

            //the invocation of the second thread!!
            service.execute(new Runnable() {
                @Override
                public void run() {
                       while(true){
                            if (queue.isEmpty()){
                                synchronized (lock){
                                     isRunning = false;   //usage of boolean
                                     lock.wait();
                                }
                            }
                            else{
                                process(queue.remove());
                            } 
                       }
                });

}

//will be called from a single thread but multiple times.
public void addToQueue(CustomClass custObj){


       queue.add(custObj);
       //I don't want blocking here!!
       if (!isRunning){
           isRunning = true;      //usage of BOOLEAN!     
           synchronized(lock){
           lock.notify();
           }
       }
}

ここで何か問題があるようですか?ありがとう。 編集: 目的: この方法では、add() が 2 回目以降に呼び出されるときに、notify() でブロックされません。メインスレッドのこのノンブロッキング動作を達成するためのより良い方法はありますか?

4

2 に答える 2

0

Queue は同期されていないため、上記のコードでは、条件変数とモニターに典型的なウェイクアップ コールが失われる可能性があります。https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem たとえば、問題のあるシーケンスは次のとおりです。実行の開始時に Q は空で、isRunning は false です。スレッド 1 (t1) は、Q が空 (真) かどうかをチェックしてから、実行を停止します。スレッド 2 (t2) より実行が開始され、addToQ メソッドが実行されます。その後、Q は空ではありませんが、t1 は実行を継続し、ロックを待機します。ノンブロッキング ソリューションが必要な場合は、Java が提供するノンブロッキング Q を使用できます ( http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html) 。もちろんjava独自のblockingQueueも使えますが、これはブロッキングです。

于 2013-06-17T11:35:24.340 に答える