1、线程池
ThreadPoolExecutor
线程池状态
new新建、runnable可运行、terminable终结、blocked阻塞、waiting等待、timed-waiting有时限等待
不可逆状态
当new状态的线程调用start()方法时,线程才会进入runnable状态,runnable状态代码执行完毕进入terminated态。如果其获取锁失败,则会进入blocked态,直到获取锁成功进入runnable态。
可逆状态
多线程争抢同一锁时,竞争失败的线程进入blocked状态,直至runnable态的线程释放锁后,其余线程重新争取锁,获取成功的线程转为runnable态。
runnable态的线程,等待某条件,调用wait()方法释放锁进入waiting态,当某条件调用noyify()后唤醒该线程,该线程重新争抢锁成功后进入runnable态。
runnable态的线程调用wait(long)(带等待时间参数的wait()方法)释放锁进入timed-waitng态,有其他线程调用notify()或等待时间到后,其被唤醒,争抢锁后转为runnable态。如果其调用sleep()方法,则不释放锁进入timed-waiting态,等到固定时长后重回runnable态。
Java中的runnable涵盖了就绪、运行和阻塞I/O
ThreadPoolExecutor中的线程状态
不同两个数分别来存状态和线程数的原因
构造方法
救急线程的执行条件
其他框架的拒绝策略
newFixedThreadPool
newCacheThreadPool
SynchronousQueue
newSingleThreadPool
提交任务
任务调度线程池
Fork/join
2、JUC
AQS
自定义不可重入锁(简易)
总体设计
完善同步器类(继承AbstractQueueSynchronizer)
获得锁通过cas确保锁状态的原子性(避免其他线程争)
线程自身释放锁且setState由volatile修饰需放在下面(考虑到写屏障)
完善其他部分
测试
—->测试成功
ReentrantLock
流程
加锁成功
加锁失败
解锁竞争成功
解锁竞争失败
原理
锁重入
可打断
不可打断(默认)
可打断
公平锁
条件变量
await
signal
读写锁
ReentrantReadWriteLock
读写锁使用
测试
—->
并发读不互斥
—->
并发写互斥
注意
StampedLock
Semaphore
CountDownLatch
线程安全集合类
线程安全集合的每个方法是线程安全的,但是组合起来不是原子的。
ConcurrentHashMap
三个线程安全的方法组合使用不安全,可以用累加器LongAdder配合compiteIfAbsent使用来实现线程安全 —->
重要属性和内部类
源码
构造器
get
put
https://www.bilibili.com/video/BV16J411h7Rd?p=284
initable
https://www.bilibili.com/video/BV16J411h7Rd?p=286
addcount
https://www.bilibili.com/video/BV16J411h7Rd?p=287
size计算流程
transfer
LinkedBlockingQueue
ConcurrentLinkedQueue
CopuOnWriteArrayList