Java JUC中操作List安全类的集合案例

网友投稿 262 2022-10-14


Java JUC中操作List安全类的集合案例

目录不安全的集合java中提供的安全措施JUC下的安全List集合性能方面

不安全的集合

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

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

import java.util.*;

public class ListTest {

public static void main(String[] args) throws InterruptedException {

// 创建list集合

//List lists = Arrays.asList("1", "2", "3");

// 不安全

List 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[] XTdNlfTargs) throws InterruptedException {

// 创建list集合

//List lists = Arrays.asList("1", "2", "3");

// 不安全

//List lists = new ArrayList<>();

List 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.utXTdNlfTil.ConcurrentModificationException报错信息。

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

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

JUC下的安全List集合

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

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

import java.util.*;

public class ListTest {

public static void main(String[] args) throws InterruptedException {

List 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();

}

}

}

查看底层源码实现逻辑

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

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

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

方式二:new CopyOnWriteArrayList();

import java.util.*;

import java.util.concurrent.CopyOnWriteArrayList;

public class ListTest {

public static void main(String[] args) throws InterruptedException {

List 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();

}

}

}

源码中的介绍如下:

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

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

调用 lock.lock() 拿到锁!

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

将新数据放入新XTdNlfT数组中。

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

性能方面

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:3GPP加密核心算法,Kasumi F8/F9解密,C代码
下一篇:如何批量快速删除国标接入设备?
相关文章

 发表评论

暂时没有评论,来抢沙发吧~