Hashtable和Collections.synchronizedMap(HashMap)之间的区别
据我所知, java.util.Hashtable
同步java.util.Map
接口中的每个方法,而Collections.synchronizedMap(hash_map)
返回一个包装器对象,其中包含将调用委托给实际hash_map
同步方法(如果我我错了)。
我有两个问题:
它使同步每一种方法和有一个包装类有什么不同? 有什么情况可以选择一种吗?
当我们做Collections.synchronizedMap(hash_table)
时会发生什么? 这是否等于简单地使用普通的java.util.Hashtable
?
以下是我从一些(希望是正确的)研究中得到的答案:
两者都提供相同程度的同步。 如果你要通过Collections.synchronized包装Hashtable
,你将获得相同的学位,但是与另一个冗余层同步。
Hashtable
和Collections.synchronizedMap(HashMap)
之间的主要区别在于API级别。 由于Hashtable
是Java的遗留代码的一部分,因此您会看到Hashtable
API得到了增强,可以实现Map
接口,从而成为Java集合框架的一部分。 这意味着,如果你包Hashtable
通过Collections.synchronizedMap()
包裹的API Hashtable
将成为受限于Map
API。 因此,如果Hashtable
的API包含在您的行为定义中,那么它显然会被更改/限制。
我可以在两个类的实现中找到另外一个差异,如下所示:
• Hashtable
类的所有方法都是同步的,即锁定是在方法级完成的,因此可以说互斥量总是处于Hashtable
对象( this
)级别。
•方法Collections.synchronizedMap(Map)
返回SynchronizedMap
的实例,它是Collections
类的内部类。 这个类在带有互斥量的Synchronized
块中有其所有方法。 不同之处在于这里的互斥体。 内部类SynchronizedMap
有两个构造函数,一个仅将Map
作为参数,另一个将Map
和Object
(mutex)作为参数。 如果通过使用一个只传递一个的第一个构造函数的默认Map
, this
是作为一个互斥。 尽管如此,开发人员可以传递另一个互斥对象作为第二个参数,通过这个参数, Map
方法上的锁定只能在该Object
,因此限制性比Hashtable
少。
•因此, Hashtable
使用方法级别同步,但Collections.synchronizedMap(Map)
为使用Synchronized
块提供的互斥锁提供了开发者锁定的灵活性。
出现在Java类库中的第一个关联集合类是Hashtable,它是JDK 1.0的一部分。 Hashtable提供了一个易于使用的,线程安全的关联映射功能,而且它确实方便。 然而,线程安全的代价是 - 所有Hashtable的方法都是同步的。 那时,无争议的同步具有可测量的性能成本。 Hashtable,HashMap(作为JDK 1.2中的Collections框架的一部分出现)的后继者通过提供非同步基类和同步包装器Collections.synchronizedMap来解决线程安全问题。 将基本功能与线程安全Collections.synchronizedMap分开允许需要同步的用户拥有它,但不需要用户的用户不必为此付费。
Hashtable和synchronizedMap同步的简单方法 - 同步Hashtable或同步的Map包装器对象上的每个方法 - 有两个主要缺陷。 这是可扩展性的一个障碍,因为一次只有一个线程可以访问哈希表。 同时,提供真正的线程安全性是不够的,因为许多常见的复合操作仍然需要额外的同步。 虽然get()和put()等简单操作可以在没有额外同步的情况下安全完成,但有几种常见的操作序列,如迭代或put-if-absent,仍然需要外部同步才能避免数据竞争。
以下链接是源代码并具有更多信息:并发集合类
链接地址: http://www.djcxy.com/p/16367.html上一篇: Difference between Hashtable and Collections.synchronizedMap(HashMap)