搜索
首页Javajava教程Java JUC怎么操作List安全类的集合

不安全的集合

在单线程应用中,通常采取new ArrayList(),指定一个List集合,用于存放可重复的数据。

但在多线程下,往往会出现意想不到的问题,代码如下所示:

import java.util.*;
public class ListTest {
    public static void main(String[] args) throws InterruptedException {
        // 创建list集合
        //List<String> lists = Arrays.asList("1", "2", "3");
        // 不安全
        List<String> lists = new ArrayList<>();

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
            new Thread(()->{
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

多线程操作同一集合对象信息,往往会出现java.util.ConcurrentModificationException异常报错信息。

Java中提供的安全措施

在java语言中,提供了一种新的List集合,java.util.Vector类,具体看下列代码:

import java.util.*;
public class ListTest {
    public static void main(String[] args) throws InterruptedException {
        // 创建list集合
        //List<String> lists = Arrays.asList("1", "2", "3");
        // 不安全
        //List<String> lists = new ArrayList<>();
		List<String> lists = new Vector<>();

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
            new Thread(()->{
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

不会出现java.util.ConcurrentModificationException报错信息。

为什么能保证数据的安全操作?

Java JUC怎么操作List安全类的集合

采取了 synchronized 针对方法执行调用者加锁,保证add操作的多线程安全性!

JUC下的安全List集合

在JUC包下,提供有以下几种创建安全集合的方式。

  • 方式一:Collections.synchronizedList(new ArrayList<>());

import java.util.*;
public class ListTest {
    public static void main(String[] args) throws InterruptedException {
		List<String> lists = Collections.synchronizedList(new ArrayList<>());

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
            new Thread(()->{
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

查看底层源码实现逻辑

Java JUC怎么操作List安全类的集合

判断传入的 list 集合类型,判断类型是否为 java.util.RandomAccess,如果是则采取java.util.Collections.SynchronizedRandomAccessList构造集合,如果不是则采取java.util.Collections.SynchronizedList构造集合。

源码中对应的add操作逻辑如下所示:

Java JUC怎么操作List安全类的集合

采取synchronized同步代码块的方式,对数据的add操作实现加锁!

  • 方式二:new CopyOnWriteArrayList();

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
public class ListTest {
    public static void main(String[] args) throws InterruptedException {
        List<String> lists = new CopyOnWriteArrayList<>();

        // 开启十个线程增加数据
        for (int i = 1; i <= 40; i++) {
            new Thread(()->{
                lists.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(Thread.currentThread().getName()+"=="+lists);
            },String.valueOf(i)).start();
        }
    }
}

源码中的介绍如下:

Java JUC怎么操作List安全类的集合

Java JUC怎么操作List安全类的集合

显而易见,其逻辑如下所示:

  1. 调用add方法后,拿到java.util.concurrent.locks.ReentrantLock对象信息。

  2. 调用 lock.lock() 拿到锁!

  3. 将原数组对象copy操作,并创建原数组大小+1的新数组。

  4. 将新数据放入新数组中。

  5. 任何操作finally,都进行锁的释放!

性能方面

JUC包下的Lock操作,都比synchronized性能更好!

以上是Java JUC怎么操作List安全类的集合的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:亿速云。如有侵权,请联系admin@php.cn删除

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境