繁体   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