线程安全的List经常在Java面试被问到,比如:线程安全的List有哪些等问题,下面我重点详解线程安全的List@mikechen
1.CopyOnWriteArrayList
CopyOnWriteArrayList是一种并发容器,它通过对底层数组进行复制来实现线程安全。
如下所示:
import java.util.concurrent.CopyOnWriteArrayList;
public class CopyOnWriteArrayListExample {
public static void main(String[] args) {
CopyOnWriteArrayList
list.add("apple");
list.add("banana");
list.add("orange");
// 创建两个线程对List进行并发访问
Thread thread1 = new Thread(() -> {
for (String fruit : list) {
System.out.println("Thread 1: " + fruit);
}
});
Thread thread2 = new Thread(() -> {
list.add("grape");
System.out.println("Thread 2: Added grape");
});
// 启动两个线程
thread1.start();
thread2.start();
}
}
在上面的代码中,我们首先:创建了一个CopyOnWriteArrayList,并向其中添加了几个元素。
接着:我们创建了两个线程,其中一个线程对List进行遍历,另一个线程向List中添加元素。
由于CopyOnWriteArrayList是线程安全的,因此这两个线程可以并发地对List进行访问,而不会出现数据不一致的问题。
2.Collections.synchronizedList
Collections类提供了一种方便的方式来创建线程安全的List,即使用synchronizedList()方法对原List进行包装,从而使其支持并发访问。
如下所示:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SynchronizedListExample {
public static void main(String[] args) {
List
list.add("apple");
list.add("banana");
list.add("orange");
// 使用synchronizedList方法创建线程安全的List
List
// 创建两个线程对List进行并发访问
Thread thread1 = new Thread(() -> {
for (String fruit : synchronizedList) {
System.out.println("Thread 1: " + fruit);
}
});
Thread thread2 = new Thread(() -> {
synchronizedList.add("grape");
System.out.println("Thread 2: Added grape");
});
// 启动两个线程
thread1.start();
thread2.start();
}
}
在上面的代码中,我们首先创建了一个普通的List,然后使用Collections.synchronizedList()方法创建了一个线程安全的List。
3.Vector
Vector是一种传统的线程安全List,它的实现方式是在每个方法上使用synchronized来进行同步。
如下所示:
public synchronized boolean add(E e) {
modCount++;
add(e, elementData, elementCount);
return true;
}
虽然Vector的实现方式比较简单,但是由于每个方法都需要加锁,所以在多线程高并发场景下效率会比较低。
4.ConcurrentLinkedDeque
ConcurrentLinkedDeque是一种非阻塞的线程安全双向队列。它的实现方式是使用一种称为”无锁队列”的算法来实现线程安全。
如下所示:
import java.util.concurrent.ConcurrentLinkedDeque;
public class ConcurrentLinkedDequeExample {
public static void main(String[] args) {
ConcurrentLinkedDeque
deque.addFirst("apple");
deque.addLast("banana");
deque.addLast("orange");
// 创建两个线程对Deque进行并发访问
Thread thread1 = new Thread(() -> {
for (String fruit : deque) {
System.out.println("Thread 1: " + fruit);
}
});
Thread thread2 = new Thread(() -> {
deque.addLast("grape");
System.out.println("Thread 2: Added grape");
});
// 启动两个线程
thread1.start();
thread2.start();
}
}
以上就是线程安全List的详解,更多线程安全,请查看:Java线程安全问题怎么解决?4种常见方式详解!