2017-07-30 4 views
0

スレッドセーフとHashMapsに関する質問があります。より具体的には、あるスレッドが書き込まれている間にHashMapからの読み込みを試みる可能性があるのでしょうか?1つのHashMap、2つのスレッド - この例でスレッド安全性を確保するにはどうすればよいですか?

私はクラスが "TestClassを" と呼ばれています:ここでは大まかな例です

public class TestClass implements Runnable { 

    // New thread 
    TestThread testThread = new TestThread(); 

    @Override 
    public void run() { 

     // Starts the thread. 
     testThread.start(); 

     // A copy of testHashMap is retrieved from the other thread. 
     // This class often reads from the HashMap. 
     // It's the only class that reads from the HashMap. 
     while (true) { 
      HashMap<String, Long> testHashMap = testThread.get(); 

     } 
    } 
} 

そして私はTestThreadと呼ばれる別のクラスを持っている:

public class TestThread extends Thread { 

    private HashMap<String, Long> testHashMap = new HashMap<>(); 

    @Override 
    public void run() { 

     // This thread performs a series of calculations once a second. 
     // After the calculations are done, they're saved to testHashMap with put(). 
     // This is the only thread that writes to testHashMap. 

    } 

    // This method returns a copy of testHashMap. This method is used by the Test class. 
    public HashMap<String, Long> get() { 
     return testHashMap; 
    } 

} 

はそれが可能ということですget()メソッド意志TestThreadによって書き込まれている間にtestHashMapをコピーしようとしていますか?もしそうなら、この例でスレッド安全性をどうやって保証するのですか? HashMapの代わりにsynchronizedMapを作成する必要がありますか?

ありがとうございます。

+0

代わりに[ConcurrentHashMap](https://docs.oracle.com/javase/8/docs/apc/java/util/concurrent/ConcurrentHashMap.html)を使用してください:https://stackoverflow.com/q/1003026/ 6505250 – howlger

答えて

1

TestThreadによって書き込まれている間にgetHashMapをコピーしようとする可能性はありますか?

いいえget()メソッドはマップを返します。ここにコピーはありません。

ただし、HashMapはスレッドセーフではないため、マップへのアクセスを何とか制御する必要があります。これを実現するには、ハッシュマップ(Map<A, B> map = Collections.synchronizedMap(new HashMap<A, B>());)を同期させるか、ConcurrentHashMapを使用します。

関連する問題