![](/img/trans.png)
[英]What happens when two threads try to modify/ access the same key in Concurrent HashMap?
[英]What Happens When two concurrent threads try to remove elements from a CopyOnWriteArrayList? java
在JAVA中,当两个并发线程试图从同一CopyOnWriteArrayList删除某些元素时会发生什么? 会有不确定的行为吗? 例如,如果列表中有1-10个整数,并且1个线程删除了前5个整数,则2个线程删除了前3个整数。准确的结果是删除了前5个整数。 这样可以正常工作吗?
CopyOnWriteArrayList的行为将取决于您使用的方法。
如果使用一个线程中的5个线程和另一个线程中的3个线程执行remove(int index)
,则将删除8个元素,尽管未定义哪个线程获取哪个元素。
如果您确实对一个线程中的5个值执行remove(Integer element)
,而在另一个线程中对前3个值进行了操作,只要没有重复项,则将删除前5个元素。 前三个元素可以被任一线程删除,而没有删除的线程将返回false
元素
如果按索引删除,则总共将删除8(5 + 3)个元素。 因为,在一个线程删除一个元素之后,新的CopyOnWriteArrayList的元素要少于早先对其执行删除的元素。
package com.copyonwrite;
import java.util.concurrent.CopyOnWriteArrayList;
public class Main {
public static void main(String[] args) {
CopyOnWriteArrayList<String> cop = new CopyOnWriteArrayList<>();
for (int i = 0; i < 10; i++)
cop.add(Integer.toString(i));
new Thread(new DeleteRunnable(cop, 5)).start();
new Thread(new DeleteRunnable(cop, 3)).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("size " + cop.size());
}
public static class DeleteRunnable implements Runnable {
CopyOnWriteArrayList<String> cop;
int cnt;
public DeleteRunnable(CopyOnWriteArrayList<String> cop, int cnt) {
this.cop = cop;
this.cnt = cnt;
}
@Override
public void run() {
for (int i = 0; i < cnt; i++)
cop.remove(i);
}
}
}
输出:大小2
CopyOnWriteArrayList
实际上是在多线程环境中使用的,其最佳结果是写入次数较少,读取次数较多 。
所有线程都携带List的副本 ,并且原始列表保持不变。 在执行任何添加/删除操作之前,Monitor会查看原始列表,每次您写入列表时都会复制整个列表,例如添加元素或删除元素并进行synchronization
。
当您的列表太大时,这可能会非常昂贵。 这意味着当我们进行少量修改但读取很多时, CopyOnWriteArrayList
最为有用,因为读取非常便宜并且不需要同步。
根据此处的文档,
java.util.ArrayList的线程安全变体,其中所有可变操作(添加,设置等)都通过对基础数组进行全新复制来实现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.