我想实现一个bean,我有一个TreeSet
,它按排序顺序存储整数。使用此TreeSet
的唯一方法是addValue
,即向集合添加新整数,getHighestValue
使用方法last()
返回集合中的最后一个值来自SortedSet
。
这里有并发问题吗?我没有使用任何显式迭代器,因此在获取最高值时不应该出现任何并发问题,但我不知道最后一个方法是否可以抛出任何ConcurrentModificationException
或任何其他异常两个线程尝试同时添加并获得最高值。
答案 0 :(得分:3)
是的,假设多个线程正在与集合交互,并且至少有一个正在修改,则存在并发问题。特别是,你提到多个线程正在进行添加操作,这肯定会导致问题 - 更糟糕的是,它们可能不会引发ConcurrentModificationException
。
ConcurrentModificationException
的目的是提醒您明显错误的并发问题,例如在迭代时尝试从集合中删除项目(它不清楚集合应该做什么,在这种情况下)。但是,只有在集合意识到错误修改时才会引发异常。由于集合不是线程安全的,因此它明确地不保证多线程操作将正确完成,并且您需要自己明确地保护集合。
最简单但效率最低的方法是在使用之前用Collections.synchronizedSortedSet()
包装集合,即:
SortedSet synchronizedSet = Collections.synchronizedSortedSet(new TreeSet());
这确保了每个方法调用都将以串行方式完成,也就是说它们将阻止等待任何先前的调用完成。但是,因此,您基本上失去了多线程的大部分好处。
另一种方法是使用明确的线程安全的SortedSet
,即ConcurrentSkipListSet
:
此实施为
log(n)
,contains
和add
操作及其变体提供了预期的平均remove
时间成本。插入,删除和访问操作由多个线程安全地同时执行。
此实现允许您从多个线程与集合进行交互,而无需进一步关注。这并不是说它是实现您正在寻找的行为的最佳方式,但是根据您所描述的内容 - 添加并访问最大值从多个线程排序的集合 - 它是您正在寻找的东西。