0

最近、ポイントを取るコンシューマでスレッド関連の問題が発生しています。これはオリジナルで、常にキューをチェックして大量の CPU を占有することを除いては正常に動作します。cuePoint をさりげなく呼び出すことができ、メイン スレッドが継続するという考え方です。

import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;


public class PointConsumer implements Runnable {
    public static final int MAX_QUEUE_SIZE=500;

    BlockingQueue<Point> queue;

    public PointConsumer (){
        this.queue=new ArrayBlockingQueue<Point>(MAX_QUEUE_SIZE);
    }

     public void cuePoint(Point p){
        try{
            this.queue.add(p);
        }
        catch(java.lang.IllegalStateException i){}
    }
     public void doFirstPoint(){
        if(queue.size()!=0){
            Point p=queue.poll();
            //operation with p that will take a while
        }
    }

    public void run() {
        while(true){
                  doFirstPoint();
        }
    }

}

cue 関数が呼び出されるたびに notify() を追加し、doFirstPoint() を次のように作り直すことで、CPU の問題を修正しようとしました。

public void doFirstPoint(){

    if(queue.size()!=0){
            //operation with p that will take a while
    }
    else{
        try{
            wait();
        }
        catch(InterruptedException ie){}
    }
}

しかし、notify() と wait() は同期関数でのみ機能することがわかりました。doFirstPoint と cuePoint を同期させると、cuePoint を呼び出したメイン スレッドが待機状態になります。

スレッドをオブジェクトにして直接通知するなど、これを回避するためのいくつかのアイデアがありましたが、それが修正されるよりも多くの問題を引き起こすか、非常に悪い形になるか、単に機能しないかはわかりませんでした. 私が見逃しているこの問題の簡単な解決策はありますか?

4

2 に答える 2

11

要点BlockingQueueは、このコードを自分で記述する必要がないことです。

代わりに呼び出すだけtake()で、オブジェクトがキューに挿入されるまで待機するか、タイムアウトを使用して、タイムアウトが経過した場合pollにのみ戻るようにします。null

編集:答えを明確にするために-コメントにあるように-これは、待機/通知コードを削除できることを意味するだけではありません。また、キューがサイズ チェックを行うので、サイズ チェックも削除します。

于 2011-03-09T21:07:58.143 に答える
3

言われたことを追加するために、put()とadd()の違いに注意することが重要です。キューがいっぱいの場合、IllegalStateExceptionがスローされ、必要に応じてput()がポイントの挿入を待機するため、挿入しようとしたポイントが実際にキューに挿入されることはありません。

add()状態のドキュメント

指定された要素をこのキューに追加します。可能な場合はすぐに追加し、成功するとtrueを返します。それ以外の場合は、IllegalStateExceptionをスローします。

状態を置きながら

指定された要素をこのキューに追加し、必要に応じてスペースが使用可能になるのを待ちます

于 2012-01-13T04:16:12.473 に答える