2

これは、私が以前に尋ねた質問に関連しています。答えは次のとおりです。

フィールドが複数のスレッドによってアクセスされる場合、そのフィールドは揮発性または最終的であるか、同期されたブロックでのみアクセスされる必要があります。そうしないと、割り当てられた値が他のスレッドに表示されない場合があります。

さらに、画面上のピクセルを操作するものはすべて、イベントディスパッチスレッドから実行する必要がありますが、これはrepaint/paintを使用すると透過的に処理されます。

したがって、私の理解では、画面上を移動するスプライトのアニメーションのような単純なもののメモリモデルについて心配する必要があります。

私の質問は、この理解は正しく、Sunのチュートリアルの例( TumbleItemソース)など)は正しくないかということです。

4

4 に答える 4

1

通常:

  1. ワーカー スレッドは何らかの計算を行い、何らかの結果に到達します。
  2. イベントキューにイベントを挿入します
  3. イベントスレッドはイベントを取得して処理します
  4. プロセス中に結果にアクセスします。

手順 (2) と (3) で適切な同期が行われています。これが、ステップ (1) の結果がステップ (4) で表示される理由です。イベント キューをどのように実装するかを考えてみてください。

于 2009-12-05T22:57:14.913 に答える
1

ThreadCheckingRepaintManagerを使用して、EDT の部分に違反したときを見つけることができます (質問に対する直接的な回答ではありませんが、それでもなお役立ちます :-)。

于 2009-12-05T23:44:37.663 に答える
1

ここで一理あると思います。TumbleItem コードはworker.isDone()、作業が完了したかどうかを調べるために使用します。ただし、これが完全な「同期」を引き起こすとは思いません。

私の JDK 1.6 コードの読み方は、それが volatile属性を持つオブジェクトをSwingWorker.isDone()使用FutureTaskするということです。の実行パスには、メソッドまたはブロックが含まれていないようです。SyncstateisDone()synchronized

私は新しい並行クラスの専門家ではありませんが、worker.get()適切な同期を保証するために、ある時点で TumbleItem を呼び出す必要があると思います。

編集: EDTimgがワーカーによって入力された配列を使用することについて言及しています。ただし、@ The Feast で指摘されているように、EDT の初期化パラメーターの使用に問題があるようにも見えます。

于 2009-12-06T00:04:59.403 に答える
0

Sun のチュートリアルが間違っていることについて、何を言いたいのかよくわかりません。

アニメーションは Swing Timer を使用して行われます。タイマーが起動すると、EDT でコードが実行されます。これは、Swing ガイドラインに従っていることを意味します。

編集:

はい、あなたの理解は正しいです。技術的には、メモリモデルについて心配する必要があります。

はい、「オフセット」は技術的には 2 つの異なるスレッドで更新されます。

a) アプレットが読み込まれるときのデフォルト スレッド

b) アニメーションが「一度」開始された EDT。

しかし、私の考えでは (物事を単純化する傾向があるかもしれません)、アプレットがロードされると、コードは単一のスレッドで実行され、オフセット値が単純に初期化されるだけです。実行中のスレッドは 1 つだけなので、同時に複数のスレッドから更新されることを心配する必要はありません。

アニメーションが開始されると、この値はアニメーションを制御するために GUI によって使用されるため、EDT のコードによってのみ更新される必要があるため、別の状況になります。

チュートリアルでは「Swing コンポーネントはイベントディスパッチスレッドで作成、クエリ、操作する必要があります」とありますが、まだ Swing コンポーネントに関しては何も始めていないので問題ないと思いますが、スレッドの専門家。

于 2009-12-05T20:58:59.740 に答える