栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

并发包下的相关类的原理概述

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

并发包下的相关类的原理概述

一、ThreadLocalRandom

     在多线程下使用单个Random实例生成随机数时,当多个线程同时计算随机数来计算新的种子时,多个线程会竞争同一个原子变量的更新操作,由于原子操作的更新是`CAS`操作,同时只有一个线程会成功,所以会造成大量线程进行自旋重试,会降低并发性能。于是产生了`ThreadLoaclRandom`。

先简单说明下ThreadLocal的原理:ThreadLocal通过让每一个线程复制一份变量,使得在每一个线程对变量进行操作的时实际上是操作自己本地内存的里面的副本,从而避免了对共享变量进行同步(要同步就一定需要加锁,Thread实现的是每个线程访问的都是自己的副本,这样就不需要进行同步处理,也就不需要加锁了)。

ThreadLocalRandom使用ThreadLocal的原理,让每个线程都持有一个本地的种子变量,该种子变量只有在使用随机数时才会被初始化。在多线程下计算新种子是根据自己线程内维护的种子变量进行更新,从而避免了竞争。

二、原子操作类(以AtomicLong为例)

AtomicLong是原子性递增或者递减类,内部使用Unsafe来实现。在没有原子类的情况下,实现计数器需要使用一定的同步措施,比如使用synchronized关键字等,由于这些都是阻塞算法,会对性能产生损耗。而AtomicLong等原子类使用CAS算法,对性能更好。但是在高并发情况下,大量线程会同时去竞争更新同一个原子变量,但由于只有一个线程的CAS操作会成功,大量的线程会竞争失败,通过无限循环不断进行自选尝试CAS的操作,会白白浪费CPU的资源。

三、JDK8新增的原子操作类LongAdder

由于AtomicLong在高并发下会导致CPU的白白浪费的问题,所以引入了LongAdder。它的思路就是把一个变量分解成多个变量,让同样多的线程去竞争多个资源。这样在同等并发量的情况下,争夺单个变量更新操作的线程量就会减少,变相的减少了争夺共享资源的并发量。此外,要是多个线程竞争失败了,不会一直自旋尝试CAS,而是尝试在其他cell的变量上进行CAS尝试。最后再获得LongAdder当前值后,把所有cell变量的value值累加后再加上base返回。

四、CopyOnWriteArrayList(并发List包只有这一个)

CopyOnWriteArrayList是线程安全的ArrayList,对其进行的操作都是在底层的一个复制的数组(快照)上进行的,也就是使用了写时复制策略。CopyOnWriteArrayList使用写时复制策略来保证list的一致性,而获取--修改--写入都不是原子性的,所以需要在增删改的过程中使用独占锁(一般使用ReentrantLock独占锁) ,来保证在某个时间只有一个线程对list数组进行修改。

此外CopyOnWriteArrayList提供弱一致性的迭代器,保证在获取迭代器后,其他线程对list数组的操作是不可见的,迭代器遍历的数组是一个快照。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/705197.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号