JUC

JUC

1、JUC概述

JUC就是java.util.concurrent工具包的简称。这是一个处理线程并发的工具包。

主要包括5大块:① executor collections atomic locks

 tools

2AQS

ReentrantLockstate初始化为0,表示未锁状态。A线程lock()时,会调用tryAcquire()占该锁并将state+1。此后,其他线程再tryAcquire()时就会失败,直到A线程unlock()state=0(即释放锁)为⽌,其它线程才有机会获取该锁。当然,释放锁之前,A线程⾃⼰是可以重复获取此锁的(state会累加),这就是可重⼊的概念。但要注意,获取多少次就要释放多么次,这样才能保证state是能回到零态的

3unsafe

通过直接操作内存的⽅式来保证并发处理的安全性,使⽤的是硬件的安全机制sun.misc.Unsafe,这个类包含了⼤量的对C代码的操作,包括很多直接内存分配以及原⼦操作的调⽤,⽽它之所以标记为⾮安全的,是告诉你这个⾥⾯⼤量的⽅法调⽤都会存在安全隐患,需要⼩⼼使⽤,否则会导致严重的后果,例如在通过unsafe分配内存的时候,如果⾃⼰指定某些区域可能会导致⼀些类似C++⼀样的指针越界到其他进程的问题,不推荐直接使⽤unsafe来操作原⼦变量,⽽是通过java封装好的⼀些类来操作原⼦变量

Unsafe 提供了以下功能:

1)内存管理

2)非常规的对象实例化 allocateInstance

3)操作类、对象、变量

4)操作数组

5)多线程同步。包括锁机制、CAS操作等

6)挂起与恢复

7)内存屏障

二、atomic

1、类型

基本类型:AtomicIntegerAtomicLongAtomicBoolean;

引用类型:AtomicReferenceAtomicReferenceABA问题(通过AtomicStampedRerenceAtomicMarkableReference解决

数组类型:AtomicIntegerArrayAtomicLongArrayAtomicReferenceArray属性原⼦修改器 (Updater):AtomicIntegerFieldUpdaterAtomicLongFieldUpdaterAtomicReferenceFieldUpdater

AtomicReference 修改对象时,会出现ABA的问题。

AtomicStampedRefer 可以避免出现ABA的问题

2、AtomicIntegerFieldUpdater

限制1:操作的⽬标不能是static类型。

限制2:操作的⽬标不能是final类型的,因为final根本没法修改。

限制3:必须是volatile类型的数据,也就是数据本身是读⼀致的。

3AtomicLong LongAdder

AtomicLong的原理

 AtomicLong是通过依靠底层的CAS来保障原⼦性,在要添加或者减少的时候,会使⽤死循环不断地cas到特定的值,从⽽达到更新数据的⽬的。

LongAdder的原理

 LongAdder是在AtomicLong的基础上将单点更新压⼒分散到各个节点,在低并发的时候通过对base的直接更新可以很好的保障和AtomicLong的性能基本保持⼀致,⽽在⾼并发的时候通过分散提⾼了性能。缺点就是LongAdder在统计的时候如果有并发更新,可能导致统计的数据有误差。

三、Tools

1、CountDownLatch

2、CyclicBarrier

3、Semaphore

限流

4、Exchanger

5、Executors

线程池,一般用executor callable future形成一个线程池框架;

线程池如何配参数?

IO型的,还是CPU密集型的。

第一种方案:如果是IO型的,可以把线程池大小配大一点儿!如果是CPU密集型的那就可以改小一点儿(根据CPU的核数去做处理)。

第二种方案:在你的机器资源足够的情况下,清楚知道你的接口的耗时是多少,要知道你的qbs多大。去设置线程数。如果qbs100,你的耗时是10ms,那就需要10个线程。

三、Executor

1、Runnable

Runnable 是一个接口,简单就一个方法,实现run方法,在run方法里编写你执行的代码,不返回数据,并且不抛异常;

2、Callable

是一个接口,有call()方法,在call()方法里编写你要执行的代码,返回执行结果,也可以抛出异常。

Runnable Callable一般不单独使用,一般配合FutrueTask加上ThreadPoolExecutor使用的

3、Future

也是1个接口,它可以对具体的Runnable 或者 Callable任务进行取消、判断是否已取消、查询任务是否完成、获取任务结果。

1、FutureTask

Future只是一个接口,无法直接用来创建对象使用,而FutureTask是一个类。它实现了RunnableFuture接口。RunnableFuture接口又继承了RunnableFuture

2、CompletableFuture

Java8后出现的。

三、ForkJoinPool

ForkJoinPool实现了ExecutorService的线程池,不同时使用了窃取机制。ForkJoinPool主要是为了执行ForkJoinTask而存在;ForkJoinPool线程池主要是为了对这些可递归可分解的任务进行调度执行。

加上⼀些对线程池⽣命周期的控制,以及提供⼀些对池的状态检查⽅法(例如 getStealCount),⽤于帮助开发、调优和监视fork/join应⽤程序

窃取机制是什么?

窃取机制是所有被ForkJoinPool管理的线程尝试窃取提交到池子里的任务来执行,执行中又可产生子任务提交到池子中

内部数据结构:ForkJoinPool采用了哈希数组+双端队列的方式存在任务。

任务分为两种:① 外部任务,通过excutesubmit提交的外部任务

② 内部任务,ForkJoinWorkerThread工作线程通过fork/join分解出来的工作任务。

外部任务映射到哈希数组的偶数槽位,提交的双端队列称之为Submission Queue;

内部任务映射到哈希数组的奇数数槽位,提交的双端队列称之为work Queue;

三、Collections

1 concurrentHashMap

是一个分段锁,segment;具体可以看(并发编程基础)

2copyOnWriteX

写时复制

 

posted @ 2021-04-14 17:04  majingyun  阅读(181)  评论(0编辑  收藏  举报