java - 如何同步传递到多个地方的实例?

标签 java multithreading synchronization

我正在编写一个代码,该代码在其构造函数中接受一个 Map,并将其分配给一个实例变量。任何使用此实例变量map的方法都会被同步。

class Foo {

   Map<Int, Int> map;

   Foo ( Map<Int, Int> map ) {
       this.map = map;
   }

   synchornized void put(int x, int y) {
       map.put(x, y);
   }

}

但是 - 客户端创建了 Foo 的多个实例,并将相同的映射实例传递给每个实例。

Map<Int, Int> map = new HashMap<Int, Int>();
new Foo(map);
new Foo(map);

在不同实例上使用map时如何同步? 让问题更广泛,如何全局同步实例?

最佳答案

您应该在 map 上同步,而不是在 foo 实例本身上同步。

void put(int x, int y) {
    synchronized (map) {
       map.put(x, y);
    }
}
<小时/>

编辑:

这里的关键点是,您需要了解同步的概念,并识别共享且需要同步的“资源”。在您的情况下,共享资源是 Map,而不是 Foo 实例本身。并发访问 Map 可能会导致问题,因此您应该同步的是共享资源 - Map 本身。

还有一些其他答案建议使用 ConcurrentHashMap。 ConcurrentHashMap 在某些情况下可以提供帮助,但它不会涵盖同步块(synchronized block)(或使用某种其他类型的锁定机制)的可能性

ConcurrentMap解决了向Map提供一些“复杂”操作的问题,这些操作过去需要多次访问,因此需要对Map进行显式锁定。 ConcurrentHashMap 更进一步,实现了线程安全的无锁读取等。

但是,这并不一定能解决问题。

假设我需要在 Map 上执行的不是提供的操作: 例如

synchronized(map) {
    if (map.contains("key1")) {
        map.put("key3", val1);
    } else if (map.contains("key2")) {
        map.put("key3", val);
    }
 }

,那么我将需要显式锁定(在这种情况下,ConcurrentHashMap 可能更糟,因为它不允许我执行显式同步)

关于java - 如何同步传递到多个地方的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22651763/

相关文章:

ios - dealloc 问题后的 dispatch_after

c++ - 难以理解 * 和 & 当它们与线程一起出现时

C- Unix 套接字 - 非阻塞读取

c# - 同步线程 - 无 UI

javascript - 有没有办法阻止 sequelize sync() 添加特定的外键?

java - 拍照后创建新文件夹

java - SwingWorker的重复执行

java - 我的 AdMob 广告未在 Android Studio 中展示

java - setOnItemClickListener() 不适用于 Fragment 中的 ExpandableHeightGridView

python - 如何通过python同步两个ftp服务器