java - 如何使用安全线程对象作为值初始化hashTable?

标签 java multithreading arraylist thread-safety hashtable

HashTable是一个线程安全的集合,但是是否使用ArrayList初始化它(因为它不是线程安全的),因为它的值危及整个线程安全方面?

 Hashtable <Employee, ArrayList<Car>> carDealership = new Hashtable<>();

进一步,我计划将ArrayLists的每个 Action 包装在synchronized块中,以防止在使用任何方法进行操作时出现任何竞争条件。

但是我还没有在HashTable中将ArrayLists声明为同步列表,这是通过以下代码实现的
 Collections.synchronizedList(new ArrayList<>())

显然,当我将ArrayLists添加到HashTable时,就会发生这种情况。

如何确定ArrayLists中的HashTable是线程安全的?

是否足以将线程安全的ArrayList传递到put()hashTable方法,我很好吗? (甚至不必担心HashTable的构造函数吗?)因此,如果我传递线程安全/不安全参数,则HashTable的put()方法甚至无法识别?

注意:线程安全是必需的。否则,我将不会选择此实现。

最佳答案

确保 Hashtable ConcurrentHashMap 中的值是线程安全的唯一方法是将其包装起来,以防止任何人添加您无法控制的内容。切勿将Map本身或其中的任何List暴露给代码的其他部分。提供方法以获取快照副本(如果需要),提供方法以将值添加到列表中,但是请确保包装 map 的类是将创建所有可以添加到列表中的列表的类。映射中“ Activity ”列表的迭代将需要外部同步(如in the JavaDocs of synchronizedList 所提及)。
HashtableConcurrentHashMap都是线程安全的,因为并发操作不会使它们处于无效状态。这意味着如果您使用相同的键从两个线程调用put,则其中一个将返回该值,另一个将作为“旧”值插入。但是,当然,如果没有一些外部同步,您将无法事先知道哪个会是第一个,哪个会是第二个。

不过,实现方式却大不相同:HashtableMap返回的同步Collections.synchronizedMap(new HashMap());类似,因为它们基本上向大多数方法添加了synchronized修饰符。如果您有很多线程(大多数情况下都是锁的争夺者)读取的最多,但偶尔会修改映射,则效率可能会很低。 ConcurrentHashMap提供了更细粒度的锁定:

Retrieval operations (including get) generally do not block



根据您的使用情况,它可以产生明显更好的性能。我还提供了具有功能强大的搜索和批量修改操作的更丰富的API。

关于java - 如何使用安全线程对象作为值初始化hashTable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49674362/

相关文章:

java - 为什么即使使用 collections.reverse() 之后 arrayList 在 java 中也不排序

java - 被paintComponent隐藏的JButtons

Java - 从多个数组中获取n个元素的组合

java - 从 Java 源文件生成 CORBA IDL?

android - 应用程序可能在 Andriod 中的主线程(Firebase 数据库)上做了太多工作

java - 在 Java 中测试并发性

java - GWT-EXT:Component.setId 生成随机前缀

java - 执行者什么时候真正创建新线程

java - 定义多维数组列表的容量

java - 使用回收无效从 arraytlist 中清除位图,ANDROID