Java多线程笔记汇总
1.基础知识
进程和线程的区别
单核与多核CPU的进程与线程
并行和并发
并发编程三个核心问题
上下文切换
并发编程适用的场景
线程安全问题
什么是锁
线程同步
2.线程的生命周期
通用线程状态
Java线程状态
轻量级阻塞与重量级阻塞
3.第一个多线程程序
创建线程
- 继承Thread
- 实现Runnable接口
Thread源码
Thread采用的模板设计模式
使用匿名内部类与Lambda创建线程
4.Thread构造函数与API
线程的命名
线程的父子关系
守护线程
线程sleep
线程yield
设置线程优先级
线程join
线程interrupt
- 可中断方法
- isInterrupted
- interrupted
ThreadGroup
5.并发三大特性
CPU与内存
- Cache模型
- CPU缓存不一致性问题
Java内存模型JMM
- 线程对主存的操作指令
- Java内存模型与硬件内存架构的关系
重排
- 编译器重排
- 处理器指令重排
可见性
- 保证可见性方法
原子性
- 互斥解决原子性问题
- CAS解决原子性问题
有序性
- 保证有序性方法
6.CAS
概念
解决原子性问题
CAS算法
CAS存在的问题
7.synchronized关键字
叫号程序
- 数据错误原因
synchronized应用方式
- 对象锁
- 类锁
- 修饰实例方法
- 修饰静态方法
- 同步代码块
synchronized实现原理
synchronized保证可见性
synchronized保证原子性
synchronized保证有序性
synchronized锁优化
- 偏向锁
- 轻量级锁
- 自旋锁
- 锁消除
synchronized关键字的缺陷
8.死锁
死锁概念
死锁需要满足的条件
9.线程间通信
为什么会有等待通知机制
生产者-消费者模型
wait和notify
wait和sleep
单线程间通信
多线程间通信
- 生产者消费者实例(多线程间通信)
存在的问题(notify和Condition)
10.volatile关键字
volatile关键字作用域
volatile写/读的内存语义
synchronized与volatile区别
volatile应用场景
Happens-Before解决可见性与有序性
- 程序顺序性规则
- volatile变量规则
- 传递性规则
- 监视器锁规则
- start()规则
- join()规则
内存屏障解决有序性问题
11.各种锁
锁分类
悲观锁 VS 乐观锁
自旋锁 VS 适应性自旋锁
synchronized锁升级
公平锁 VS 非公平锁
可重入锁 VS 非可重入锁
独享锁 VS 共享锁
12.线程池
手动创建线程的缺点
创建线程过程
线程池作用
ThreadPoolExecutor
- 三大方法
- 七大参数
- ThreadPoolExecutor工作情景
- 四大拒绝策略
为什么不推荐使用Executors
13.队列同步器AQS
队列同步器概念
同步器可重写的方法
同步状态State方法
同步器提供的模版方法
自定义互斥锁
AQS架构图
AQS同步队列
- Node节点及waitStatus
- 同步队列的结构
非公平锁加锁与解锁过程
代码实现独占式获取同步状态
- lock(ReentrantLock)
- acquire(AbstractQueuedSynchronizer)
- tryAcquire(ReentrantLock):如何体现非公平
- 公平锁与非公平锁tryAcquire方法
- addWaiter(enq)线程加入队列
- acquireQueued
代码实现独占式释放同步状态
- unlock
- AQS#release
独占式tryLock
独占式tryLock(timeout, unit)
独占式响应中断获取同步状态lockInterruptibly
14.Lock
避免死锁
Lock与synchronized
Lock接口
Lock使用范式
Lock是怎样起到锁的作用
15.ReentrantLock
ReentrantLock与AQS的关系
可重入锁
公平锁与非公平锁
- 公平锁与非公平锁实现原理
- 为什么有公平锁与非公平锁设计
tryLock(time, unit)实例
ReentrantLock与synchronized
16.Condition
Condition接口
同步队列与等待队列
newCondition
AQS#ConditionObject
await()
signal/signalAll
生产者-消费者Condition
参考资料
1.Archives | 日拱一兵——非常棒!