您好,欢迎访问一九零五行业门户网

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报错信息。
为什么能保证数据的安全操作?
采取了 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();        }    }}
查看底层源码实现逻辑
判断传入的 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<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();        }    }}
源码中的介绍如下:
显而易见,其逻辑如下所示:
调用add方法后,拿到java.util.concurrent.locks.reentrantlock对象信息。
调用 lock.lock() 拿到锁!
将原数组对象copy操作,并创建原数组大小+1的新数组。
将新数据放入新数组中。
任何操作finally,都进行锁的释放!
性能方面juc包下的lock操作,都比synchronized性能更好!
以上就是java juc怎么操作list安全类的集合的详细内容。
其它类似信息

推荐信息