Oh *_*oon 15 java arraylist synchronized
当我们说ArrayList不同步时它意味着什么?
这是否意味着如果我们在对象范围内声明一个ArrayList,访问对象的多个线程有机会修改列表?
aio*_*obe 11
当我们说ArrayList不同步时它意味着什么?
这意味着ArrayList从多个线程访问实例可能不安全(读取,"可能导致意外行为"或"可能无法像宣传的那样工作").
进一步阅读:
这是否意味着如果我们在对象范围内声明一个ArrayList,访问对象的多个线程有机会修改列表?
即使它是线程安全的,多线程也能够修改列表.
不同之处在于,如果它不是线程安全的并且多个线程访问列表,那么所有的赌注都是关闭的.假设该类不是线程安全的,就像添加"如果一次从一个线程访问,此方法如下工作......"在每个方法描述前面.
无论是否同步,ArrayList 始终可以被多个线程修改。同步是关于防止并发访问。
使用 ArrayList(或一般的 Collections)有两个并发问题。
首先,有方法同步。这意味着,对 ArrayList 实例的所有方法的调用都是同步的。所以一次总是只执行一个方法。第一个方法仍在计算时发生的所有其他方法调用都将排队,直到正在运行的方法完成。
可以通过像这样包装 ArrayList 来确保方法同步:
List list = Collections.synchronizedList(new ArrayList());
Run Code Online (Sandbox Code Playgroud)
示例:假设两个线程同时尝试执行以下操作:
list.add(0, "test");
Run Code Online (Sandbox Code Playgroud)
如果您有一个同步列表,则可以保证列表后记以两个“测试”条目开头。如果列表未同步,您可能会得到一个只有一个“测试”条目的列表……或其他意外结果。
第二,有实例同步。在这里,我们不仅防止并发方法调用,而且确保在一段时间内只有一个线程可以访问列表对象。如果您的逻辑片段要求列表在逻辑完成之前保持不变状态,那么这一点很重要。例如迭代列表。您不希望其他线程在迭代列表时添加元素。
这种同步是通过用一个同步块包装你的逻辑块来完成的:
synchronized(list) {
for (Object o:list) {
...
}
}
Run Code Online (Sandbox Code Playgroud)