簡體   English   中英

在多個線程之間共享一個有效不可變的 object

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM