JUC(锁/并发容器/原子类/并发工具类)
2021-03-02 18:27:53 2 举报
AI智能生成
JUC(锁/并发容器/原子类/并发工具类)
作者其他创作
大纲/内容
阅读导航
<b style=""><font color="#0076b3">线程 👉</font></b>
<b><font color="#0076b3">CPU+JMM</font></b> 👉
<b><font color="#0076b3">CAS+Volatile</font></b> 👉
<b><font color="#0076b3">Synchronized</font></b> 👉
<b><font color="#0076b3">JUC</font></b>
<b><font color="#f15a23">locks锁+atomic原子类</font></b>
<b><font color="#0076b3">executor自定义线程池</font></b> 👉
<b><font color="#0076b3">collections并发容器</font></b> 👉
<b><font color="#0076b3">tools并发工具类</font></b> 👉
<b><font color="#0076b3">线程池</font></b> 👉
<b style="font-size: inherit;"><font color="#0076b3">ThreadLocal</font></b><span style="font-size: inherit;"> 👉</span><br>
Lock 接口
ReentrantLock
原理:CAS+AQS 👉
请求线程先通过CAS尝试修改state状态位获取锁,如果没有获取到,就加入AQS队列<br>并且被挂起,当锁被释放之后, 排在队首的线程会被唤醒,通过CAS再次尝试获取锁
AQS
实现
独占锁
ReentrantLock
共享锁
CountDownLatch|CyclicBarrier|Semaphore
原理
AQS的实现依赖内部的同步队列,队列内部维护了一个state域和一个FIFO的双向链表,如果当前线程竞争锁(修改state状态)失败<br>那么AQS会把当前线程加入到同步队列中,同时阻塞该线程。当获取锁的线程释放锁以后,会从队列中唤醒队首的阻塞节点
公平与非公平
如果是非公平锁, 新进来的线程会尝试竞争锁,竞争不到才去排队;如果是公平锁,新来的线程会直接排到队尾,由队首的线程获取到锁
重入锁
现象:如果当前线程已经持有锁了,释放锁之前线程自己是可以重复获取此锁的(state会累加)这就是可重入的概念<br>但要注意获取多少次就要释放多少次,最后保证state能回到零态
原理:AQS的父类维护了一个属性,用来存储当前持有锁的线程ID,每次获取锁的时候对比线程ID看是否可重入
LockSupport
用于创建锁和其他同步类的基本线程阻塞原语,方法park()和unpark()提供了阻止和解除阻塞线程的有效手段
park():禁止当前线程进行线程调度,除非许可证可用
unpark(Thread thread):为给定的线程提供许可证(如果尚未提供)
Condition 接口
一个Condition实例本质上绑定到一个锁来使用,相当于一个队列,要获得特定Condition实例要调用 lock.newCondition();
await():使当前线程等待 发信号或 interrupted
signal():唤醒当前队列的一个等待线程
signalAll():唤醒所有等待线程<br>
ReadWriteLock 接口
ReentrantReadWriteLock
读写锁维护着一对锁,一个读锁和一个写锁。通过分离读<br>锁和写锁,使得并发性比一般的排他锁有了较大的提升
在同一时间,可以允许多个读线程同时访问
在写线程访问时,所有读线程和写线程都会被阻塞
特点
公平性:支持公平锁和非公平锁
重入性:支持重入锁
锁降级:遵循获取写锁,再获取读锁,最后释放写锁的次序,如此写锁能够降级成为读锁
高频面试题
<b><font color="#662c90">要求使用两个线程,交替打印出 1A2B3C4D5E6F7G</font></b>
<font color="#662c90">方式一:使用Lock结合Condition完成</font>
<font color="#662c90">方式二:使用LockSupport完成</font>
ReentrantLock如何避免死锁?
响应中断 lockInterruptibly()
可轮询锁 tryLock()
定时锁 tryLock(long time)
lock和lockInterruptibly的区别?
lock 和 lockInterruptibly,如果两个线程分别执行这两个方法,但此时<br>中断这两个线程, lock 不会抛出异常,而 lockInterruptibly 会抛出异常
tryLock和lock的区别?
tryLock 能获得锁就返回 true,不能就立即返回 false
lock 能获得锁就返回 true,不能的话一直等待获得锁
tryLock(long timeout,TimeUnit unit),可以增加<br>时间限制,如果超过该时间段还没获得锁,返回 false
Synchronized和Lock的区别?
lock是接口,属于API层面,Synchronized是关键字,属于JVM层面
Synchronized是非公平锁,ReentrantLock两者都可以,默认非公平
Synchronized可以给方法和代码块加锁,lock只能给代码块加锁
ReentrantLock是自动释放锁,不会死锁;ReentrantLock需要手动释放锁<br>如果忘记unlock()则会出现死锁,所以我们一般会在finally中使用unlock()
ReentrantLock更加灵活,结合Condition.signal(),可以给指定wait()对象解锁
atomic(原子类)
基本类型
AtomicBoolean
AtomicInteger
AtomicLong
基本类型数组
AtomicIntegerArray
AtomicLongArray
更新字段
AtomicIntegerFiledUpdater
AtomicLongFiledUpdater
AtomicReferenceFieldUpdater
引用类型
AtomicReference
AtomicMarkableReference
AtomicStampledReference
AtomicReferenceArray
累加器
LongAdder
DoubleAdder
LongAccumulator
DoubleAccumulator
关于作者
<b style=""><font color="#b296c7">我的博客</font></b> 👉
<b><font color="#00a650">微信公众号</font></b> 👉
<b><font color="#f15a23">GitHub 导航</font></b> 👉
<b><font color="#662c90">ProcessOn 主页 👉</font></b>
0 条评论
下一页