如果我有 Iterator
在多个线程之间共享,每个线程调用:
// Inside a thread
int myValue = iterator.next();
可能的结果是什么?
(忽略next()可能抛出nosuchelementexception的事实)如果迭代器是arraylist上的迭代器,是否有可能多个线程在 myValue
变量?
下面的代码是解决此问题的一种方法吗(除了使用这里描述的Java8流之外(在java中向多个线程传递一个列表迭代器)。
// Inside a thread
int myValue;
synchronized(iterator)
{
myValue = iterator.next();
}
3条答案
按热度按时间d8tt03nd1#
是不是多个线程在myvalue变量中可能以相同的值结束?
不能保证。
自
iterator
不是线程安全的,您应该在集合的对象上同步。a0x5cqrl2#
tldr公司;不要在线程之间共享迭代器!
考虑到迭代器在内容上循环的最常见用法,您可能会遇到以下代码段:
现在考虑另一个线程执行完全相同操作的可能性。由于无法控制线程调度,因此在具有单个元素的迭代器上可能会发生以下情况:
迭代器也可以支持
Iterator.remove()
,这会导致ConcurrentModificationException
在共享集合上操作时。我们能在不同的线程中得到相同的值吗?
以与上面类似的方式,考虑这个非常简单的迭代器实现(简化代码):
在这里,我们可能会得到:
答案是肯定的,但需要注意的是,这在很大程度上取决于实现。完全不去那里要安全得多。
重复:一般来说,您不应该在线程之间共享迭代器。
pbgvytdp3#
行为
List#iterator()
是不一致的List
实现。ArrayList
,LinkedList
,将抛出ConcurrentModificationException
如果在迭代过程中修改。要避免这种情况,请使用synchronizedlist()并锁定List
在迭代过程中。Vector
是由迪富尔特同步的,但是Iterator
不是线程安全的。CopyOnWriteArrayList
,我们可以迭代List
即使在迭代过程中并发修改也很安全。