[英]Sharing an effectively immutable object between multiple threads
下面 hashmap 中的更新值是否會反映在閱讀器線程中(線程不會修改 hashMap 的 state)? 如果改用ConcurrentHashMap
會怎樣?
public class SharedDataTest {
private static class SomeWork implements Runnable {
private Map<String, String> dataTable;
public SomeWork(Map<String, String> dataTable) {
this.dataTable = dataTable;
}
@Override
public void run() {
//do some stuff with dataTable
}
}
public static void main(String[] args) {
Map<String, String> dataTable = new HashMap<String, String>();
dataTable.put("someKey","someValue");
Runnable work1 = new SomeWork(dataTable);
Runnable work2 = new SomeWork(dataTable);
new Thread(work1).start();
new Thread(work2).start();
}
}
如果 map 的所有初始化都在啟動線程之前完成,則不需要額外的同步。 線程的開始將充當 memory 屏障,並且在該線程開始之前發生的任何事情對該線程都是可見的。
請注意,如果您在線程啟動后更改 map,則無法保證線程是否或是否會看到該更改。
是的,它會反映出來,但取決於您對run()
方法所做的操作,可能會出現不一致,因為您沒有在外部同步。 使用Collections.synchronizedMap(map)
或更好地使用ConcurrentHashMap
,它將免費為您提供線程安全
public SomeWork(Map<String, String> dataTable) {
this.dataTable = Collections.synchronizedMap(dataTable);
}
檢查 HashMap 的文檔,該文檔要求在並發的情況下進行外部同步
請注意,此實現不同步。 be * synchronized externally. * 如果多個線程同時訪問一個 hash map,並且至少有一個線程在結構上修改了 map,則在外部同步。 (結構修改是添加或刪除一個或多個映射的任何操作*;僅更改與實例已包含的鍵關聯的值 * 不是結構修改。)這通常通過 * 在某些 object 上同步來完成自然地封裝了 map。
最好使用ConcurrentHashMap
而不是外部同步 map。
public class SharedDataTest {
private static class SomeWork implements Runnable {
private Map<String, String> dataTable;
public SomeWork(Map<String, String> dataTable) {
this.dataTable = dataTable;
}
@Override
public void run() {
//do some stuff with dataTable
}
}
public static void main(String[] args) {
Map<String, String> dataTable = new ConcurrentHashMap<String, String>();
dataTable.put("someKey","someValue");
Runnable work1 = new SomeWork(dataTable);
Runnable work2 = new SomeWork(dataTable);
new Thread(work1).start();
new Thread(work2).start();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.