并发
2021-05-28 17:49:10 2 举报
AI智能生成
CAS、AQS
作者其他创作
大纲/内容
并发
Synchronized
javap --> 反编译代码:有一个monitor enter指令,多个monitor exit指令(避免发生异常导致不能monitor exit)
AQS
原理
1、State(volatile)
模板模式:根据自己同步器需要满足的性质实现线程获取和释放资源的方式(修改同步状态变量State的方式)
三种访问方式
1、getState()
2、setState()
3、compareAndSetState():CAS保证了节点的原子性
使用volatile保证了head、tail节点操作中的有序性和可见性
2、CLH 内部队列
Node节点
1、wateStatus
CANCELLED:1 说明该线程中断或者等待超时,需要移除该线程
SIGNAL: -1 处于唤醒状态,只要前继结点释放锁,就可执行该线程
CONDITION: -2 与Condition(条件队列)相关,该标识的结点处于等待队列中;当其他线程调用了Condition的signal()方法后,CONDITION状态的结点将从等待队列转移到同步队列中,等待获取同步锁。
PROPAGATE: -3 在共享模式中,该状态标识结点的线程处于可运行状态。
2、prev(阻塞队列):是同步线程队列中保存的前置节点的地址。
3、next(阻塞队列):是同步线程队列中保存的后续节点的地址。
4、thread:同步线程队列主要存储的线程信息。
5、nextWaiter(条件队列):条件队列是使用单向列表保存的,用nextWaiter来连接。
子主题
2种队列
1、同步队列
原理:当线程获取资源失败后,就进入同步队列的尾部保持自旋等待;不断判断自己是否是链表的头节点;如果是头节点,就不断参试获取资源,获取成功后则退出同步队列。
2、条件队列
原理:是为Lock实现的一个基础同步器,并且一个线程可能会有多个条件队列,只有在使用了Condition才会存在条件队列。
3、两种资源共享的方式
1、独占锁
概念:同一时刻只允许一个线程访问共享资源
类
ReentrantLock
2、共享锁
概念:同一时刻允多个线程访问共享资源
Semaphore
核心思想(可用于限流方案):可以认为Synchronized代表的是一把锁,那么Semaphore就是多把锁。
核心方法
1、Semaphore(int permits):构造方法,创建具有给定许可数的计数信号量并设置为非公平信号量。
3、void acquire():从此信号量获取一个许可前线程将一直阻塞。相当于一辆车占了一个车位。
4、void acquire(int n):从此信号量获取给定数目许可,在提供这些许可前一直将线程阻塞。比如n=2,就相当于一辆车占了两个车位。
5、void release():释放一个许可,将其返回给信号量。就如同车开走返回一个车位。
6、void release(int n):释放n个许可。
7、int availablePermits():当前可用的许可数。
CountDownLatch
1、new CountDownLatch(4):此时会创建一个AQS的同步队列,并把创建CountDownLatch 传进来的计数器赋值给AQS队列的 state(4).
2、countDownLatch.wait():会创建一个节点,加入到AQS阻塞队列,并同时把当前线程挂起。
3、countDownLatch.down():AQS内部是通过释放锁的方式,对state进行减1操作,当state=0的时候,将AQS阻塞队列里的节点线程全部唤醒。
4
LockSupport.park():作用是阻塞当前线程
LockSupport.unpark(Thread):停止阻塞某线程
实质:实质都是通过UnSafe类使用了CPU的原语
作用:让排队的线程阻塞掉(停止其自旋,自旋会消耗CPU资源),并在需要的时候,可以方便的唤醒阻塞掉的线程。
CAS
1、依赖Unsafe类中的font color=\"#c41230\
2、CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做(然后自旋)。
实现类
AtomicInterger(限流)
缺点
1、ABA问题。
AtomicStampedReference/AtomicMarkableReference来处理会发生ABA问题的场景,主要是在对象中额外再增加一个标记来标识对象是否有过变更。
2、循环时间长开销大。自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。
线程
线程池
四种线程池
1、SingleThreadExecutor
单例线程池:循环使用,只会有一个线程。
2、CachedThreadPool
缓存线程池:可重用线程,如果没有可用的线程,既新增;移除那些已有 60 秒钟未被使用的线程。因此,长时间空闲的线程池不会占用任何资源。
3、FixedThreadPool
定长线程池:指定工作线程数量的线程池,提交一个任务新建一个线程,直到饱和;如何工作任务达到线程的最大数,既存入池队列中。
4、ScheduledThreadPool
周期线程池:创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。(延时)
核心参数
1、corePoolSize:核心线程数
核心线程会一直存活,及时没有任务需要执行
当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理
设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭
2、queueCapacity:任务队列容量(阻塞队列)
当核心线程数达到最大时,新任务会放在队列中排队等待执行
3、maxPoolSize:最大线程数
当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务
当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常
4、keepAliveTime:线程空闲时间
当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize
如果allowCoreThreadTimeout=true,则会直到线程数量=0
0 条评论
回复 删除
下一页