Java并发包中常用类小结(一)

从JDK1.5以后,Java为我们引入了一个并发包,用于解决实际开发中经常用到的并发问题,那我们今天就来简单看一下相关的一些常见类的使用情况。

1、ConcurrentHashMap

ConcurrentHashMap其实就是线程安全版本的hashMap。前面我们知道HashMap是以链表的形式存放hash冲突的数据,以数组形式存放HashEntry等hash出来不一致的数据。为了保证容器的数据一致性,需要加锁。HashMap的实现方式是,只有put和remove的时候会引发数据的不一致,那为了保证数据的一致性,我在put和remove的时候进行加锁操作。但是随之而来的是性能问题,因为key-value形式的数据,读写频繁是很正常的,也就意味着我有大量数据做读写操作时会引发长时间的等待。为了解决这个问题,Java并发包问我们提供了新的思路。在每一个HashEntry上加一把锁,对于hash冲突的数据,因为采用链表存储,公用一把锁。这样我才在做不同hash数值的数据时,则是在不同的锁环境下执行,基本上是互不干扰的。在最好情况下,可以保证16个线程同时进行无阻塞的操作(HashMap的默认HashEntry是16,亦即默认的数组大小是16)。

那ConcurrentHashMap是如何保证数据操作的一致性呢?对于数据元素的大小,ConcurrentHashMap将对应数组(HashEntry的长度)的变量为voliate类型的,也就是任何HashEntry发生变更,所有的地方都会知道数据的大小。对于元素,如何保证我取出的元素的next不发生变更呢?(HashEntry中的数据采用链表存储,当读取数据的时候可能又发生了变更),这一点,ConcurrentHashMap采取了最简单的做法,hash值、key和next取出后都为final类型的,其next等数据永远不会发生变更。

另外ConcurrentHashMap采用的锁结构是将读和写分开的,大大的提升了性能,下面我们来看一下两者之间的性能差。

由于数据比较密集,我们分开来看一下

相关数据如下:

分析表

元素个数

10

100

1000

10000

线程数

容器类别

增加

删除

查找

增加

删除

查找

增加

删除

查找

增加

删除

查找

1

HashMap

2805

1743

1520

3004

1726

1579

1995

1846

1528

2032

1787

1501

ConcurrentHashMap

4947

2010

1699

5292

2005

1661

2322

1842

1243

2351

2113

1541

10

HashMap

29814

36539

28076

31180

55178

38156

31217

36756

31785

33314

30497

26488

ConcurrentHashMap

18364

22086

8064

21420

22805

9932

20164

20875

7800

19383

19483

10254

50

HashMap

233674

193918

230404

205577

221995

213651

343005

318603

343153

249921

229954

234555

ConcurrentHashMap

131573

98534

16778

152609

96412

24233

123199

108388

20156

134971

122927

18799

100

HashMap

313442

309336

302591

332389

314167

296360

343005

318603

343153

329171

352704

354593

ConcurrentHashMap

161866

122582

21369

141274

114333

21875

116758

97985

24098

140902

120459

18766

(神马情况 数据看不到了 弄一个图吧)

我们可以看到,在单线程下,ConcurrentHashMap的综合性能略低于HashMap,但是随着线程的增长,ConcurrentHashMap的优势就明显提现出来了,尤其是查找元素的性能。因此并发情况下,ConcurrentHashMap是代替HashMap的一个不错的选择。

2、CopyOnWriteArrayList

同样的,CopyOnWriteArrayList是线程安全版本的ArrayList。和ArrayList不同的是,CopyOnWriteArrayList默认是创建了一个大小为0的容器。通过ReentrantLock来保证线程安全。CopyOnWriteArrayList其实每次增加的时候,需要新创建一个比原来容量+1大小的数组,然后拷贝原来的元素到新的数组中,同时将新插入的元素放在最末端。然后切换引用。

针对CopyOnWriteArrayList,因为每次做插入和删除操作,都需要重新开辟空间和复制数组元素,因此对于插入和删除元素,CopyOnWriteArrayList的性能远远不如ArrayList,但是每次读取的时候,CopyOnWriteArrayList在不加锁的情况下直接锁定数据,会快很多(但是可能会引发脏读),对于迭代,CopyOnWriteArrayList会生成一个快照数组,因此当迭代过程中出现变化,快照数据没有变更,因此读到的数据也是不会变化的。在读多写少的环境下,CopyOnWriteArrayList的性能还是不错的。

3、CopyOnWriteArraySet

CopyOnWriteArraySet是基于CopyOnWriteArrayList实现的。但是CopyOnWriteArraySet鉴于不能插入重复数据,因此每次add的时候都要遍历数据,性能略低于CopyOnWriteArrayList。

4、ArrayBlockingQueue

ArrayBlockingQueue是基于数组实现的一个线程安全的队列服务,其相关的功能前面我们已经用到过了,这里就不多提了。

5、Atomic类,如AtomicInteger、AtomicBoolean

我们来看以下对应的API文档

这种原子类是基于JDK的CAS的无阻塞操作,比我们写同步的效率要高多了哦。

对于Atomic类我们在后面的示例中也会很频繁的使用,这里也就不多介绍了。

Java并发包中常用类小结(一)相关推荐

  1. Java并发包中常用类

    Java并发包中常用类小结(一) 从JDK1.5以后,Java为我们引入了一个并发包,用于解决实际开发中经常用到的并发问题,那我们今天就来简单看一下相关的一些常见类的使用情况. 1.Concurren ...

  2. Java八大常用类小结

    Java的八大常用类 文章目录 Java的八大常用类 1.内部类 内部类的优点 2.Object类 3.包装类 4.数学类(Math类) 5.时间类 6.String类 7.String Builde ...

  3. java并发编程中常用的工具类 Executor

    /***************************************************  * TODO: description .  * @author: gao_chun  * ...

  4. java零基础Ⅱ-- 4.常用类

    java零基础Ⅱ-- 4.常用类 一.包装类 包装类的分类 包装类和基本数据的转换 演示 测试题 包装类型和String类型的相互转换 Integer类和Character类的常用方法 Integer ...

  5. 详解Java多线程编程中LockSupport类的线程阻塞用法

    转载自  详解Java多线程编程中LockSupport类的线程阻塞用法 LockSupport类是Java6(JSR166-JUC)引入的一个类,提供了基本的线程同步原语.LockSupport实际 ...

  6. 第 5-6 课:Java 并发包中的高级同步工具 + 面试题

    Java 中的并发包指的是 java.util.concurrent(简称 JUC)包和其子包下的类和接口,它为 Java 的并发提供了各种功能支持,比如: 提供了线程池的创建类 ThreadPool ...

  7. java 8 Stream中操作类型和peek的使用

    文章目录 简介 中间操作和终止操作 peek 结论 java 8 Stream中操作类型和peek的使用 简介 java 8 stream作为流式操作有两种操作类型,中间操作和终止操作.这两种有什么区 ...

  8. Java遍历包中所有类包括jar包(完整转载)

    第一部分转自 :http://blog.csdn.net/wangpeng047/article/details/8124390 第二部分转自:http://blog.csdn.net/wangpen ...

  9. Java遍历包中所有类

    由于项目需要,我想获得某包下所有的类(包括该包的所有子包),从网上找了找,没有什么能用的,即使找到了写的也不怎样,效率低下.索性就自己写吧,正好也锻炼锻炼写代码的功底.特此分享出来,希望能帮到大家.. ...

最新文章

  1. nagios全攻略(三)----使用插件监控更多信息
  2. Matlab心得及学习方法(不断更新)
  3. rocketmq怎么保证消息一致性_从入门到入土(三)RocketMQ 怎么保证的消息不丢失?...
  4. HTML5 通过 FileReader 实现文件上传
  5. php stream 函数集
  6. c4d fbx大小_C4D一键竖排文字预设 建模辅助
  7. Beta版本测试报告
  8. 二叉树、多叉树子路径遍历
  9. Discuz支持反对提示:抱歉您的请求来路不正确或表单无法提交的解决方法
  10. ASP 中用Ctrl+Enter提交表单
  11. JavaScript 3D 散点图
  12. mtk x20 android 开发环境配置
  13. Mac大小写切换需长按capslock键解决办法
  14. BAT机器学习面试1000题系列大集合整理(320)
  15. 压力传感器如何直接连接电脑笔记本采集数据表格导出
  16. 去重插入数据 mysql_mysql 数据去重
  17. 织梦banner图后台添加
  18. cad图片边框怎么去掉
  19. 文件太大notepad 打不开怎么办
  20. 奇安信技术支持实习生面试

热门文章

  1. python库——pprint
  2. 步骤带图详细解释margin、padding、border、content
  3. npm升级到最新版本
  4. Chrome开发者工具详解
  5. 计算机室部简介ppt,计算机学院分团委部门简介(1)
  6. vue3+ts+vite自适应项目——搭建项目
  7. sql查询数据库注释(表及表注释,字段及字段注释)
  8. 【确实不错】10本最值得推荐的区块链书
  9. [附源码]计算机毕业设计Python的个人理财系统(程序+源码+LW文档)
  10. delphi mysql 删除_Delphi 用SQL语句添加删除修改字段