【发布时间】:2018-04-05 14:03:59
【问题描述】:
HashTable 是一个线程安全的集合,但使用 ArrayList(不是线程安全的)作为值初始化它会危及整个线程安全方面吗?
Hashtable <Employee, ArrayList<Car>> carDealership = new Hashtable<>();
此外,我计划将 ArrayLists 的每个操作包装在 synchronized 块中,以防止在使用任何方法时出现任何竞争条件。
但我还没有将 HashTable 中的 ArrayLists 声明为同步列表,这是通过以下代码实现的
Collections.synchronizedList(new ArrayList<>())
当我将 ArrayLists 添加到 HashTable 时,就会发生这种情况。
如何确定HashTable 中的ArrayLists 是线程安全的?
将线程安全的ArrayList 传递给hashTable 的put() 方法就足够了吗?(甚至不用担心HashTable?) 因此 HashTable 的 put() 方法甚至无法识别我是否正在传递线程安全/不安全参数?
注意:线程安全是一项要求。否则我不会选择这个实现。
【问题讨论】:
-
旁注:
Hashtable是线程安全的,但您不使用ConcurrentHashMap 是否有特定原因?它提供了更强大的 API。 -
@Hulk 主要是因为 HashTable 有一个快速失败的迭代器,我也想测试一下。使用 ConccurentHashMap 仍然无法解决我必须将 List 作为值传递的问题。
-
是的,好的,
ConcurrentHashMap上的迭代会迭代快照,并且不会因ConcurrentModificationException而失败。我并不是说使用ConcurrentHashMap可以解决你的问题,我只是好奇你为什么考虑使用古老的Hashtable。 -
在
ConcurrentHashMap或Hashtable中替换一个列表(被声明为同步的)确实会引发一个不安全的线程问题,如下面的答案所述? -
@Hulk 正如我所说,我计划将 ArrayLists 的每个操作包装在一个同步块中,以防止在使用任何方法操作时出现任何竞争条件。现在回到问题的答案,发帖人承认 HashTable 实际上可能会使引用处于无效状态。毕竟我的解决方案是线程安全的吗?
标签: java multithreading arraylist thread-safety hashtable