Java中线程安全的集合

Posted XeonYu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中线程安全的集合相关的知识,希望对你有一定的参考价值。

上一篇:
JUC中的常用辅助类(CountDownLatch、CyclicBarrier、Semaphore)

在之前的文章中,我们已经解释过线程安全的概念了。

我们之前大多是通过加锁的方式去解决集合的线程安全问题,也用了一下线程安全的Vector。
除了Vector,还有一些其他的方法来使用线程安全的集合。

通过Collections类获取线程安全的集合

比如,通过 java.util 包下面的 Collections 工具类来获取线程安全的集合。

先来看看Collections中都有哪些方法
在这里插入图片描述

如图所示,我们可以通过 Collections.synchronizedList 来获取一个线程安全的List。

同样的,Collections也提供了获取线程安全的 mapset。使用方式都是类似的。

我们先来看看synchronizedList的源码
在这里插入图片描述
可以看到,很多方法内部都用了synchronized代码块,所以是线程安全的。
其他的synchronizedMapsynchronizedSet 等方法都是类似的原理。

我们来简单用一用:

先来看个普通的ArrayList

    public static void main(String[] args) {

        List<String> strings = new ArrayList<>();

        for (int i = 0; i < 20; i++) {
            int finalI = i;
            new Thread(() -> {
                strings.add(String.valueOf(finalI));
                System.out.println("strings = " + strings);
            }).start();
        }

    }

运行一下:
在这里插入图片描述

可以看到,多运行几次,偶尔会出现 java.util.ConcurrentModificationException
并发修改异常,我们在之前的文章中已经看到过了。

我们改成 Collections.synchronizedList(new ArrayList<>()) 试一下。

代码如下:

    public static void main(String[] args) {

        List<String> strings = Collections.synchronizedList(new ArrayList<>());

        for (int i = 0; i < 20; i++) {
            int finalI = i;
            new Thread(() -> {
                strings.add(String.valueOf(finalI));
                System.out.println("strings = " + strings);
            }).start();
        }

    }

运行结果如下:

在这里插入图片描述

可以看到,再也不会出现 并发修改异常了。


JUC中线程安全的集合

JUC是专门处理并发的包,那肯定也给我们提供了线程安全的集合类。

在这里插入图片描述

如图所示:

常用的比如:

  • CopyOnWriteArrayList
  • ConcurrentHashMap
  • CopyOnWriteArraySet
  • ArrayBlockingQueue

等等
我们看下 CopyOnWriteArrayList 某个方法的源码

在这里插入图片描述
可以看到,内部是通过使用ReentrantLock实现的线程安全。

简单用一用:

    public static void main(String[] args) {
        CopyOnWriteArrayList<String> stringCopyOnWriteArrayList = new CopyOnWriteArrayList<>();

        for (int i = 0; i < 20; i++) {
            int finalI = i;
            new Thread(() -> {
                stringCopyOnWriteArrayList.add(String.valueOf(finalI));
                System.out.println("strings = " + stringCopyOnWriteArrayList);
            }).start();
        }

    }

运行看下效果:
在这里插入图片描述

可以看到,也不会出现并发修改异常。


如果你觉得本文对你有帮助,麻烦动动手指顶一下,可以帮助到更多的开发者,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!

以上是关于Java中线程安全的集合的主要内容,如果未能解决你的问题,请参考以下文章

Java面试宝典线程安全问题|线程死锁的出现|线程安全的集合类

Java并发多线程编程——集合类线程不安全之HashMap的示例及解决方案

Java并发多线程编程——集合类线程不安全之HashSet的示例及解决方案

Java并发多线程编程——集合类线程不安全之ArrayList的示例及解决方案

Java中线程安全的集合

Java中线程安全的集合