我试图了解synchronizedCollection
,synchronizedList
,synchronizedMap
,synchronizedSet
和其他此类方法的作用。据我了解,同步可以在块和方法上完成,而不能在类上完成,所以让我们说一下我是否有一个哈希映射。
HashMap<Integer,String> hashMap = new HashMap<Integer,String>();
HashMap<Integer,String> syncHashMap = Collections.synchronizedMap(hashMap);
问题
所以上述代码只是同步了整个syncHashMap
类,还是
里面的每个方法?
如果我们可以简单地使用线程安全集合,例如
在多线程方案中使用ConcurrentHashMap
或SynchronizedMap
,那么有什么需要
Collections.synchronizedMap(hashMap)
和其他类似方法
集合类
在此先感谢您的指导。
答案 0 :(得分:1)
不确定同步的整个syncHashMap类和其中的每个方法是什么意思。
如果查看方法Collections.synchronizedMap(hashMap)
的源代码,您会发现它使用synchronized
关键字来修饰原始地图的每个方法。这意味着对于装饰的地图对象,您一次只能调用其方法之一。但是不同的地图,您可以一次调用它们。
答案 1 :(得分:0)
那么上面的代码只是同步了整个syncHashMap类或其中的每个方法吗?
从Collections.syncrhonized*
返回的集合实际上是自定义实现,其方法在互斥体上同步。例如,这是Collections.synchronizedMap
的实现:
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
return new SynchronizedMap<>(m);
}
看看SynchronizedMap
的某些方法,我们看到:
public int size() {
synchronized (mutex) {return m.size();}
}
public boolean isEmpty() {
synchronized (mutex) {return m.isEmpty();}
}
public boolean containsKey(Object key) {
synchronized (mutex) {return m.containsKey(key);}
}
如果我们可以在多线程场景中简单地使用诸如ConcurrentHashMap或SynchronizedMap之类的线程安全集合,那么Collections类中的Collections.synchronizedMap(hashMap)和其他类似方法有什么需求
Collections#synchronized*
对于要确保在给定时间在任何线程上仅执行集合的一种方法很有用。这也称为更新一致性。
答案 2 :(得分:0)
据我所知Collections.synchronizedMap
不保证存储对象内的字段值将被同步,但是在{{1 }} 方法。它不保证其他任何内容。每当在另一个线程中修改同步映射时,其他线程中相同映射的其他引用将同步。
根据source和Java文档,这是我对此的肤浅理解。
答案 3 :(得分:0)
有几个术语涉及您要询问的主题。
有许多接口和类可以帮助您在线程之间同步代码。 Semaphore,CyclicBarrier或类似BlockingQueue的同步集合。有关这些类的列表,请参见java.util.concurrent软件包。
synchronized
块也是一种同步方式,尽管正确地使用它{em> 需要更多经验。
不同的语言(和库)以不同的方式实现标准互斥。想法保持不变-为了继续执行特定代码(互斥令牌),必须获取互斥体。在Java中,此获取发生在进入synchronized
块之前。
简单地说,一个类可以同时从任意数量的线程以任何顺序访问其所有方法时,它是线程安全的。有几种实现线程安全的方法。例如,字符串是线程安全的。它们不同步,但是它们是不可变的,这也导致线程安全。所有Collections.synchronized*()
方法都返回集合的线程安全包装器,并规定所有对它们的未来*(*请参见happens-before关系)访问都是通过这些包装器执行的(这就是初学者调用{仅Collections.synchronized*()
个对象上的{1}}。
具有前几段的知识,可以回答您的问题:不,它不会同步类。它根本不会改变原始的new
实现。
但是,它确实为该类创建了一个读写线程安全的同步可变代理。
答案 4 :(得分:0)
在回答您的问题之前,让我们重申一些同步基础知识
要回答您的问题:
是的。只需查看Collections.SynchronizedMap here的源代码即可。注意,几乎每种方法都有 synchronized(mutex)块。
那么同步每个方法(包括只读类型的方法)都有缺点。它不必要地减慢了读取操作的速度,因此您的观察是正确的,即使用诸如ConcurrentHashMap的实现仅锁定正在修改集合的方法的实现。只读方法不同步,因此在多线程情况下并发读/写操作会更快。
Collections.synchronizedMap提供的唯一优势是保留输入键的顺序。因此,在需要时可以使用Collections.synchronizedMap。