线程安全List详解(4种线程安全List)

线程安全List详解(4种线程安全List)-mikechen

线程安全的List经常在Java面试被问到,比如:线程安全的List有哪些等问题,下面我重点详解线程安全的List@mikechen

1.CopyOnWriteArrayList

CopyOnWriteArrayList是一种并发容器,它通过对底层数组进行复制来实现线程安全。

如下所示:

import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteArrayListExample {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> list = new 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<String> list = new ArrayList<>();
        list.add("apple");
        list.add("banana");
        list.add("orange");

        // 使用synchronizedList方法创建线程安全的List
        List<String> synchronizedList = Collections.synchronizedList(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<String> deque = new 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种常见方式详解!

陈睿mikechen

10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获取更多技术干货!

后台回复面试即可获取《史上最全阿里Java面试题总结》,后台回复架构,即可获取《阿里架构师进阶专题全部合集

评论交流
    说说你的看法