concurrent

更新时间:2023-01-01 03:40:01 阅读: 评论:0


2023年1月1日发(作者:春运来啦)

Java线程安全的集合con_rent包中线程安全的

集合简介

⼀、线程安全的集合

Java中有很多⽀持多线程并发的集合,⽐如Hashtable、Vector但是这些“古⽼”的并发集合效率并不⾼,⼀般只⽀持⼀个线程对其进⾏

读写(加锁是针对整张表)。从Java5开始Java在rent包中提供了更多,效率更⾼的线程安全集合。下⾯⽤⼀张图⽚来显⽰

这些集合的继承实现关系。

注:java也可以使⽤collections⼯具类的⽅法获取⼀个线程安全的集合。

如上图所⽰,Java考虑的⾮常周全,分别为Map、List、Queue、Set四种类型提供了新的线程安全集合类。下⾯将重点介绍其中的

ConcurrentHashMap、CopyOnWriteArrayList,因为这两者代表了两类并发实现思想,介绍了它们的特性,其他的也就⾃然清楚了。

⼆、CopyOnWriteArrayList简介

CopyOnWriteArrayList顾名思义就是在写操作之前先复制⼀份,这样读操作不⽤加锁,写操作在复制的集合上修改,然后将新集合赋值给

旧的引⽤,并通过volatile保证其可见性,当然写操作的锁是必不可少的了。

正式因为这种利⽤空间换时间的思想,CopyOnWriteArrayList需要注意内存占⽤问题,⽐较好的实践是,尽量在添加的时候做批量添加。

三、ConcurrentHashMap简介

ConcurrentHashMap本质上还是⼀个HashMap,它⽀持多个线程同时对它进⾏读写操作。在默认情况下,ConcurrentHashMap⽀持

16个线程同时进⾏读写操作。那么它实现这种特性的原理是什么呢?

(1)它在并没有在读操作上加锁,只是在写操作上进⾏了加锁——volatile应⽤和happen-before原则。

(2)分段加锁:ConcurrentHashMap把⾃⼰分成多个段(gment),每个段其实是⼀个⼩HashTable,如果多个线程访问的段不同,那么

就可以进⾏并发操作,其实主要思想就是加锁的粒度更⼩了⽽已。

(3)对于需要对整个集合加锁的⽅法,⽐如size(),它会按顺序加锁,操作完毕后,再按加锁顺序释放锁。

下⾯⽤代码来⽐较⼀下使⽤Hashtable和ConcurrentHashMap的并发效率,分别⽤1万个线程对它们执⾏写操作,通过对任务的完成时间

来进⾏⽐较并发性能。

packagecom;

ar;

;

ble;

rentHashMap;

orService;

ors;

publicclassMain{

publicstaticvoidmain(String[]args)throwsException{

//⽐较⼀下HashTable和ConcurrentHashMap的效率

finalHashtableh_table=newHashtable<>();

finalConcurrentHashMapconMap=newConcurrentHashMap<>();

//开启2W个线程,每个集合1w个线程进⾏写⼊操作,计算时间性能

//记录开始时间

Calendarstart_time=tance();

start_e(newDate());

//开启⼀个线程池1W个线程往Hashtable中写数据

ExecutorServicepool1=hedThreadPool();

for(inti=1;i<=10000;i++){

finalintj=i;

(newRunnable(){

publicvoidrun(){

h_(j,"任务:"+j);

}

});

}

wn();

while(!inated()){

//空循环等待线程池中的线程执⾏完成

}

//记录完成时间,打印出时间差

Calendarf_time1=tance();

f_e(newDate());

n("Hashtable上读写耗时:"+(f_eInMillis()-start_eInMillis()));

//开启⼀个线程池1W个线程往ConcurrentHashMap中写数据

ExecutorServicepool2=hedThreadPool();

for(inti=1;i<=10000;i++){

finalintj=i;

(newRunnable(){

publicvoidrun(){

(j,"任务:"+j);

}

});

}

wn();

while(!inated()){

//空循环等待线程池中的线程执⾏完成

}

//记录完成时间,打印出时间差

Calendarf_time2=tance();

f_e(newDate());

n("ConCurrentHashMap上读写耗时:"+(f_eInMillis()-f_eInMillis()));

}

}

结果如下:

Hashtable上读写耗时:250

ConCurrentHashMap上读写耗时:70

四、总结

rent包提供的线程安全类,主要是利⽤copy-on-write读写优化策略和分段加锁策略,来提⾼并发性。在⼤量多线程的场景

中选择它们是⽐较合适的(在线程不多的时候未必能体现时间上的优势)。

本文发布于:2023-01-01 03:40:01,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/69736.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

下一篇:stockholm
标签:concurrent
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图