3

私はこのようなものを持っているとしましょう(そして私は持っています)

class QueBean extends JPanel {
    private Queue queue = new LinkedBlockingQueue();

    public Object poll(){
        return queue.poll();
    }
}

これらのいくつかは独自のスレッドで実行されます

class ConsumerBean extends JPanel implements Runnable{
    private QueBean queBean;

    public synchronized run(){
        while (true) {
           Object result =  queBean.poll();
           if (result != null) {
              jResultTextField.setText("got one");  
           }
           wait(500);
        }
    }
}

poll()はいるQueBeanべきsynchronizedかどうか?

4

4 に答える 4

6

スレッドの問題がありますが、あなたが考えているものではありません。あなたが投稿したコードはほぼ間違いなく違法であり、最終的にはロックされます。

Swing のコア ルールの 1 つは、1 つのスレッドのみが「実現された」コンポーネントにアクセスできるということです。(実現とは、画面上または「ほぼ」画面上にあることを意味します)。

これ:

jResultTextField.setText("got one"); 

スレッドの内部は間違いなく間違っています。それはできません。画面の更新を AWT スレッドに取得するには、invokeLater または invokeAndWait を確認してください。

ところで、コンポーネントを拡張するものにスレッドを使用するのはおかしいと思います。それを見ると、競合がどこにあったのかをすぐに検索することになりますが、長年の Java プログラマーは一目で不安になるはずです。クラスをいくつか分割し、GUI (コントローラー) を駆動する部分を GUI (ビュー) から完全に分離します。

于 2010-02-10T18:15:47.097 に答える
2

この場合、外部同期は必要ありません。BlockingQueue契約書を読む:

BlockingQueue の実装はスレッドセーフです。すべてのキューイング メソッドは、内部ロックまたはその他の形式の同時実行制御を使用して、アトミックに効果を達成します。

于 2010-02-10T18:17:32.357 に答える
2

いいえ、必要ありません。pollメソッドはスレッドセーフなメソッドを呼び出す以外は何もしないため、データが破損する可能性はありません。

于 2010-02-10T18:07:10.843 に答える
1

queueで変更されない限り、これを行う必要はありませんQueBean

また、ある種の些細なレート制限を実装しようとしているのでない限りwait(500)、コードにを含める必要はありません。キューがブロックされているため、不要です。

于 2010-02-10T18:14:24.120 に答える