0

プログラムが実行するコマンドを含む配列リストが空かどうかをチェックする while ループがあります。明らかに、空でない場合は機能しますが、現在の場合は、他に Thread.sleep(1000) があります。そのため、それとやり取りするものはすべてかなり遅くなります。新しいコマンドが追加されるまで、実行中のスレッドをブロックする方法はありますか? (それはそれ自身のスレッドで実行されるので、それが私にとって最良の解決策のようです)または、これに対するより良い解決策はありますか?

4

3 に答える 3

5

とを使用wait()して、リストに何かを追加するnotify()スレッドに、読み取るものがあることをコンシューマ スレッドに通知させることができます。ただし、これには適切な同期などが必要です。

しかし、問題を解決するより良い方法は、BlockingQueue代わりに a を使用することです。定義上、それらは同期されたクラスであり、デキューは適切にブロックされ、ものが追加されるとウェイクアップします。LinkedBlockingQueueキューを制限したくない場合に使用するのに適したクラスです。制限された数のArrayBlockingQueueアイテムをキューに格納する場合 (またはLinkedBlockingQueueコンストラクターに整数を渡す場合) に使用できます。限られたキューqueue.add(...)の場合、キューがいっぱいになるとブロックされます。

BlockingQueue<Message> queue = new LinkedBlockingQueue<Messsage>();
...
// producer thread(s) add a message to the queue
queue.add(message);
...
// consumer(s) wait for a message to be added to the queue and then removes it
Message message = queue.take();
...
// you can also wait for certain amount of time, returns null on timeout
Message message = queue.poll(10, TimeUnit.MINUTES);
于 2012-07-12T17:44:59.103 に答える
3

コマンドには a を使用しBlockingQueue<E>ます。
上記のリンクには、それを使用する方法の非常に良い例があります。

于 2012-07-12T17:45:32.363 に答える
2

より良い解決策は、ExecutorService を使用することです。これは、キューとスレッドのプールを組み合わせたものです。

// or use a thread pool with multiple threads.
ExecutorService executor = Executors.newSingleThreadExecutor();

// call as often as you like.    
executor.submit(new Runnable() {
    @Override
    public void run() {
        process(string);
    }
});

// when finished
executor.shutdown();
于 2012-07-12T17:54:24.027 に答える