私はJavaでカプセル化されたスレッドセーフなデータ構造へのアクセスを同期する必要がありますか?
-
19-09-2019 - |
質問
私はこのような何かを持っている(と私は)言います
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
すべきかどうかを判断する?
解決
外部同期は、この場合には必要ありません。 BlockingQueue
の契約を読みます:
BlockingQueueの実装があります スレッドセーフ。すべてのキューイング方法 使用してアトミックにその効果を達成 内部ロックまたは他の形態 同時実行制御ます。
他のヒント
がありスレッドの問題があるが、あなたが考えるものではない - あなたが投稿したコードは、ほぼ確実に違法であり、最終的にはロックアップします。
。スイングのコアルールの一つは、一つだけスレッドが「実現」コンポーネントをタッチさせることです。 (実現手段の画面上または「ほぼ」オンスクリーン)。
この:
jResultTextField.setText("got one");
スレッドInsideは、間違っていることはかなり確信している - あなたはそれを行うことはできません。あなたのAWTスレッド上に画面の更新を取得するためにinvokeLaterまたはinvokeAndWaitのを確認します。
は、ところで - それは、コンポーネントを拡張するものでスレッド持つ面白い感じている - すぐに競合があった場所を検索するために私を導くシーイングが、それはglance--で不安任意の長時間Javaプログラマをしなければなりません私はあなたには、いくつかのあなたのクラスを分割し、完全に駆動させる部分を分離示唆あなたのGUI GUI(ビュー)から(コントローラ)..
はありません。必要はありません。あなたのpoll
メソッドはスレッドセーフなメソッドを呼び出すことを除いて何もしないので、データの破損の可能性はありません。
あなたはとても長いqueue
がQueBean
では変更されませんので、これを実行する必要はありません。
また、あなたはあなたのコード内でwait(500)
を必要としません。それが原因キューがブロックであることに余計です。