📅  最后修改于: 2023-12-03 15:01:52.358000             🧑  作者: Mango
CopyOnWriteArrayList 是一个线程安全的 List,它使用了写时复制的机制来保证线程安全。在操作时,它会先复制一份原有数据,然后在复制出来的数据上进行修改,最后将原有数据引用指向新的数据,这就保证了线程安全。
CopyOnWriteArrayList 提供了 addIfAbsent(E e) 方法,它的作用是向 List 中添加元素 e,当元素 e 不存在时才添加。
该方法的函数签名如下:
public boolean addIfAbsent(E e)
该方法的作用是添加元素 e 到 List 中,当 List 中不存在元素 e 时才添加,并且返回添加是否成功。如果 List 中已经存在元素 e,则该操作不会执行添加,并返回 false。
下面是使用示例:
import java.util.concurrent.CopyOnWriteArrayList;
public class AddIfAbsentDemo {
private static CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
if (list.addIfAbsent(1)) {
System.out.println("Thread 1 added element 1");
} else {
System.out.println("Thread 1 failed to add element 1");
}
if (list.addIfAbsent(2)) {
System.out.println("Thread 1 added element 2");
} else {
System.out.println("Thread 1 failed to add element 2");
}
});
Thread t2 = new Thread(() -> {
if (list.addIfAbsent(1)) {
System.out.println("Thread 2 added element 1");
} else {
System.out.println("Thread 2 failed to add element 1");
}
if (list.addIfAbsent(3)) {
System.out.println("Thread 2 added element 3");
} else {
System.out.println("Thread 2 failed to add element 3");
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("List contents: " + list);
}
}
输出结果:
Thread 1 added element 1
Thread 1 added element 2
Thread 2 failed to add element 1
Thread 2 added element 3
List contents: [1, 2, 3]
在上述示例中,两个线程同时尝试向 List 中添加元素,并且其中一个线程添加了已经存在的元素。由于使用了 addIfAbsent() 方法,该操作失败并且返回 false,不会影响到 List 中的内容。
总的来说,CopyOnWriteArrayList 的 addIfAbsent() 方法可以保证线程安全的添加元素操作,并且可以避免重复添加元素。