首先,根据下面的Javadoc:
如果多个线程同时访问ArrayList实例,并且至少有一个线程在结构上修改了列表,则必须在外部进行同步。 (结构修改是添加或删除一个或多个元素的任何操作,或显式调整后备数组的大小;仅设置元素的值不是结构修改。)
不需要同步。
另一方面,设置元素的值是原子操作,因此不能交错。但是,仍然可能存在内存一致性错误。
哪个是对的?
编辑:也许我没有表达清楚。实际上,我只是想知道Javadoc是错误的还是至少是误导性的。顺便说一句,我说设置元素的值是一个原子动作,但这显然是错误的。
答案 0 :(得分:2)
我想你想要的是保证在迭代器的生命周期中调用[app:main]
use = config:development.ini#main
sqlalchemy.uri = postgresql://....
时迭代器不会失效。我认为这是从一个List.set(int, E)
实现到另一个List
实现的不同,所以如果文档没有明确说明List.set(int, E)
是线程安全的,那么假设它不是。在实践中,您可能会发现数组实现不会使迭代器失效,但您不希望依赖第三方库中的任何未记录的行为 - 如果您想强制执行某些条件,则应该在您自己的代码中执行此操作。 / p>
确保List.set(int, E)
不会使迭代器无效的类的示例:http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html
答案 1 :(得分:1)
我不认为对ArrayList
中的值设置如何实现进行假设是一个好主意。重要的是,如果在Javadoc中没有给出一致性保证,那么当多个线程使用相同的ArrayList
时,应始终在外部进行同步。
或者,根据用例,选择一个不同的结构,一个专为并发而设计的结构,如CopyOnWriteArrayList
。 (虽然总是确保你选择正确的,因为他们在任何情况下都不会表现得同样好。)
在这种情况下,如果您只使用set()
,Javadoc并没有明确表示您可以省略同步,而只是提示它。提示是错误的,因为正如你所说,内存一致性根本没有保证,你可以很容易地读取陈旧的值,或者可以重新排序多个set()
调用。
答案 2 :(得分:0)
如果你需要同步一个ArrayList,你似乎对使用哪个组件做出了错误的决定。您应该使用同步的Vector