2011-06-29 11 views
1

私は以下のようなクラスがあり、スレッドセーフであるか、メインスレッドとLoaderスレッドがmCacheの独自のコピーを持つ可能性があるため、get(..)メソッドローダースレッドで追加されたキャッシュから何かを取得できませんか?これをvolatileとする必要がありますか?インスタンス変数とスレッディング

ありがとうございます!

public class StackExample 
{ 
    private final ConcurrentHashMap<String, SoftReference<Bitmap>> mCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>(); 

    private addToCache(String key, Bitmap bitmap) 
    { 
     mCache.put(key, bitmap); 
    } 

    private Bitmap getBitmap(String key) 
    { 
     if(mCache.contains(key)) 
     { 
      return mCache.get(key); 
     } 
     else 
     { 
      //add to loading queue 
     } 
    } 

    private class Loader extends Thread 
    { 
     @Override 
     public void run() 
     { 
      ...//check loading queue and load some images here 
      mCache.put(keyString, new SoftReference<Bitmap>(loadedBitmap)); 
     } 
    } 
} 
+0

すべてのスレッドに一意の* mCache *が表示されますが、コードはまだ正しく同期されていません。あなたは* from * getBitmap *がどこから呼び出されているかは完全にはっきりしていませんが、*同じキー*のコードの一部を読み込みキューに追加する*ことがあります* !?)。 – SyntaxT3rr0r

+0

btw +1あなたの質問には、あなたの非常に細かい質問をアップvotingせずにジョン・スケートの一行の回答をアップした人々に恥をかく。感謝! – SyntaxT3rr0r

+0

ありがとう!はい、ここでは簡単な例ですが、私はあなたが意味するものは何を意味するか知っています:) – Dori

答えて

4

(この場合は空の)変数が最終的なもので、それは、コンストラクタの前にすべてのスレッドに表示されます戻ります。

+0

それは変更可能ではありませんか?最終的なフィールドは、自分のcopysを保持するスレッドに影響されませんか? – Dori

+1

@Dori:あなたは何をコピーすると思いますか? 'ConcurrentHashMap'は変更可能ですが、ロックなしで複数のスレッドが使用するように設計されています。 –

+0

申し訳ありませんが、私はおそらく、すべての変数が、それらを使用する各スレッドによってすべての変数をローカルコピーとして保持でき、スレッドがその変数に他のスレッドが行った変更を表示できない可能性があるという誤った印象を受けました。いくつかの状況では、volatileキーワードはこれを防ぐことができますが、インターリーブされた操作は停止しません。また、私は同期インターリーブされた操作を停止したと思ったが、ローカルコピー/変数のキャッシングにどのような影響があるのか​​わからない - sycnronisedブロックの開始/終了時に変数がリフレッシュ/メインメモリにプッシュされる? – Dori

0

volatileは、各スレッドがフィールドの値のキャッシュを保持しないことを意味します。 mCacheフィールドに書き込むことができた場合、別のスレッドによって設定された直後にフィールドを読み取るときに、別のスレッドが新しい値を取得したことを確認したい場合は、volatileと宣言します。

+0

私はフィールドがちょうどリファレンスであり、最終的には – Dori

+0

であるので、これはケースに合わないと思った。それが変更できないときにそれを揮発性と宣言する理由はない –

関連する問題