2

スレッドの制限については明確ではありません。Swing では、すべての GUI コンポーネントを EDT を通じて更新する必要があります。SwingWorker は長時間の操作のために Java6 で提供されており、done メソッドで GUI コンポーネントを更新できます。私の理解では、done() メソッドの GUI コンポーネントは EDT で更新されます。したがって、同期の問題は発生しません。しかし、ここにリンクテキスト

それは言います:

ImageRetriever クラスは画像をダウンロードして大きなラベルに配置するため、コンストラクターでラベルと画像の URL を指定すると便利です。ImageRetriever には、画像を取得するための URL が必要です。ImageRetriever インスタンスがラベルのアイコン自体を設定できるように、ラベルを提供します。内部クラスを使用する場合、ワーカー スレッドが情報に直接アクセスできるため、コンストラクターでこの情報を提供することさえできない場合があります。ただし、コンストラクターで情報を提供すると、その情報が ImageRetriever インスタンス間で共有されないため、アプリケーションをよりスレッドセーフにするのに役立ちます。

私はこれについて混乱しています。SwingWorker メソッドが EDT の GUI コンポーネント (リンクの例では JLabel) を更新する場合、ImageRetriever(=SwingWorker) インスタンス間でそれらを共有しない方がスレッドセーフである理由は何ですか? 複数の SwingWorker があり、done() メソッドで同じコンポーネントを更新する場合、更新に同期プリミティブを使用する必要がありますか? 私は何か誤解していますか?スレッドの制限は、1 つのスレッドだけがすべてのアクションを実行することを意味しませんか? swingworkers はスレッドに制限されていませんか?

ありがとう

4

1 に答える 1

1

ラベルが親クラスで宣言され、何らかの理由でその変数に新しい値が割り当てられた場合、すべての swingworker が更新を確認します。これは、EDT が物事を更新している間に発生する可能性があるため、奇妙な動作につながる可能性があります。

例えば:

SW in EDT - label.setText(...);
Thread1 - label = new JLabel();
SW in EDT - label.setIcon(...);

ラベル変数が共有されている場合、一貫性のない状態 (テキストまたはアイコンのないラベル) が得られます。

更新 コンストラクターを介して渡される変数としてラベルを格納することは、この問題を回避する方法です。変更を確認したいが、メソッドの実行途中ではない場合は、メソッドのローカル変数を使用する方法があります。メソッドの先頭に割り当てて、外部で変更されないようにします。

内部クラスと親クラスの属性を使用する場合、これは次のようになります。

public void done() {
  JLabel l = label;
  l.setText(...);
  l.setIcon(...);
} 

変数が SW の属性として定義されている場合、メイン クラスに格納されている値を取得する何らかの方法を作成する必要があります (例: ゲッター)。

于 2010-09-04T20:26:33.693 に答える