Collection.synchronizedMap VS同步的HashMap中的各个方法
-
19-09-2019 - |
题
是什么Collections.synchronizedMap()和围绕HashMap中的包装与同步的所有方法之间的差异。我没有看到监守Collections.synchronizedMap(任何差)在内部维护所有的方法相同的锁。
基本上,是什么下面的代码段之间的差
Class C {
Object o;
public void foo() {
synchronized(o) {
// thread safe code here
}
}
}
和
Class C {
Object o;
public synchronized void foo() {
}
}
解决方案
有只有一个区别:
Collections.synchronizedMap 是能够使用不同的显示器比本身。
使用同步方法是与使用sychnchonized(this)
块,这意味着,包装器将是显示器,可以从包装物的外侧被锁定。
如果你不希望外部的应用程序来锁定您的显示器,你需要将其隐藏。
在另一边,如果你想调用多种方法在一个线程安全的方式,它是锁定整个集合最简单的方法(但不是很可扩展的,确实)。
PS:对于重复使用,最好是委托方法调用比备份地图覆盖类,因为以后可以切换到另一个地图的实现,而无需更改包装
其他提示
这两种方法获得的对象在监视器等应执行完全相同。这种差异的主要原因是建筑。同步的包装允许轻松扩展基本非线程安全的变化。
说了这么多不要么使用,使用的ConcurrentHashMap。它使用锁分离所以它的要快得多比任何方法使用(因为它们是相同的开销+争而言)。锁条带允许在背衬阵列段被独立地锁定。这意味着它是不太可能的两个线程将请求获取同一个锁。
不要重新发明轮子和使用什么是由API提供。
您应该总是装点,而不是结块样样feartures成一个大专题类。
始终以普通地图和与类别装饰,或使用的java.util.concurrent和使用真实的锁,因此可以以原子检查和更新地图。明天你可能要Hashtable中更改为树状图,你就会有麻烦,如果你坚持一个哈希表。
那么,你为什么要问? :)你真的相信,如果类被放置在java.util包中,然后一些神奇的发生及其Java代码在一些棘手的方式?
它实际上只是包含与同步{}块,仅此而已的所有方法。
UPD:不同的是,你有很多机会少犯错误,如果你使用同步的,而不是自己做所有的东西同步收集
。 UPD 2:如可以在源看到他们使用“mutex'-对象作为监视器。当在方法的签名(即synchronized void doSmth()
)你的对象的当前实例(即this
)使用同步改性剂用作监视器。下面的代码的两个块是相同的:
1
synchronized public void doSmth () {
someLogic ();
moreLogic ();
}
synchronized public static void doSmthStatic () {
someStaticLogic ();
moreStaticLogic ();
}
2
public void doSmth () {
synchronized (this) {
someLogic ();
moreLogic ();
}
}
public static void doSmthStatic () {
synchronized (ClassName.class) {
someStaticLogic ();
moreStaticLogic ();
}
}
如果线程安全性的情况下,使用包并发数据结构。使用包装类将降低所有访问,以地图为顺序队列。
A)的线程等待在地图完全不同的点做操作将等待相同的锁。基于线程的数目这会影响应用性能。
b)考虑在地图上化合物的操作。使用包装用单锁也无济于事。例如。 “你看如果存在的话再加入”之类的操作。线程同步化将再次成为一个问题。