Bu yazida thread safe hashmap ile ilgili ornek yapacagiz.
Once thread safe olmayan bir ornek yapalim.
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class UnsafeMap {
public static void main(String[] args) throws InterruptedException {
Map cricketMap = new HashMap();
cricketMap.put("Australia", 349);
cricketMap.put("India", 257);
ExecutorService executorService = Executors.newFixedThreadPool(10);
Runnable task = new Runnable() {
@Override
public void run() {
incrementScore(cricketMap, "India");
}
};
for(int i=0; i<100 :="" ap="" cricketmap.get="" executorservice.awaittermination="" executorservice.shutdown="" executorservice.submit="" i="" inal="" incrementscore="" india="" integer="" is="" ndia="" of="" private="" score="" static="" system.out.println="" task="" timeunit.seconds="" tring="" void=""> teamMap, String team) {
Integer score = teamMap.get(team);
teamMap.put(team, score +1);
}
}
100>
Yukaridaki ornekte India nin score unu 100 arttirdik. Sonucun 258 olmasini bekliyoruz ama her seferinde baska sonuc cikiyor.
Final score of India is : 353
Final score of India is : 352
gibi. Neden ?
Cunku
since multiple threads try to modify the HashMap concurrently, the change done by one thread gets overridden by some other thread, and the output becomes non-deterministic.
Bunu onlemek icinse ornegimizi thread safe yapalim. Yani sadece ayni anda tek bir thread erisebilsin. Bunun icin yapacagimiz iki sey sunlar olmali :
- Use the Collections.synchronizedMap() method to obtain a synchronized view of the HashMap.
- Write the increment logic inside a synchronized block.
Son halde kodumuz su sekilde olur:
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Safemap {
public static void main(String[] args) throws InterruptedException {
Map cricketScore = Collections.synchronizedMap(new HashMap());
cricketScore.put("Turkey", 52);
cricketScore.put("Germany", 170);
//we are creating thread pool with size 10
ExecutorService executorService = Executors.newFixedThreadPool(10);
Runnable task = new Runnable() {
@Override
public void run() {
incrementScore(cricketScore, "Turkey");
}
};
for(int i=0; i<100 :="" ap="" cricketscore.get="" executorservice.awaittermination="" executorservice.shutdown="" executorservice.submit="" i="" inal="" incrementscore="" integer="" is="" of="" private="" score="" static="" system.out.println="" task="" timeunit.seconds="" tring="" turkey="" urkey="" void=""> scoreMap, String team) {
synchronized (scoreMap) {
Integer score = scoreMap.get(team);
scoreMap.put(team, score +1);
}
}
}
100>
Turkiyenin score unu 100 arttirdik. Threas safe oldugu icin her zaman 152 donecektir.
Final score of Turkey is : 152
Final score of Turkey is : 152
Hiç yorum yok:
Yorum Gönder