
Java并发编程.png
Java并发编程
并发编程的优势
提升CPU资源利用率
- CPU缓存
- 操作系统分时复用
- 指令流水线优化
提升吞吐量
提升程序响应速度
更好的编程模型
并发带来的问题
安全性问题
-
定义:多线程读写共享变量时出现不正确的行为
-
原因
-
原子性问题
- CPU时钟中断带来的线程切换
-
可见性问题
- 多核CPU高速缓存之间不可见
-
重排序问题
-
CPU和编译器会进行重排序指令
- 典型问题:单例模式DCL
-
-
-
解决方案
-
解决可见性问题和重排序
-
Java内存模型(JMM)
-
按需禁用缓存和编译优化(重排序)
- volatile
- final
Happens-Before规则
-
-
-
解决原子性问题
-
通用互斥锁管程模型
-
管程
管理并发过程中的共享变量及其操作过程
-
MESA模型
线程阻塞队列
条件变量
条件变量等待队列
-
编程范式
-
while循坏检测
- 虚假唤醒
- 条件变更
-
-
sychronized
对象头锁结构
monitorenter和monitorexit
-
锁升级
- 偏向锁
- 轻量级锁
- 重量级锁
-
-
volatile变量读写+cas无锁算法
LOCK指令总线锁
MESI缓存一致性协议
unsafe工具类
-
CAS三大注意事项
- ABA问题
- 循坏开销大
- 多变量问题
-
-
并发同步工具和机制
基于AQS的同步组件
-
原子变量
- AtomicLong
- LongAdder
-
等待通知机制
- wait
- notify/notifyAll
-
线程封闭
- ThreadLocal
非阻塞同步机制
-
-
活跃性问题
-
死锁
-
定义
- 一组相互竞争资源的线程因互相等待,导致”永久“阻塞的现象
-
死锁的四大条件
-
互斥
- 共享资源只能被一个线程占用
-
占有且等待
- 已占有资源的线程,在等待其他资源时不释放原有资源
-
不可抢占
- 线程不能抢占其他线程已占有的资源
-
循环等待
- 出现线程之间相互等待对方资源的情况
-
-
打破死锁
-
打破“占有且等待”
- 一次性申请所有资源
-
打破“不可抢占”
-
已占有资源的线程,如果申请不到其他资源,主动释放原有资源
- 并发包的LOCK
-
-
打破“循环等待”
- 按统一顺序申请资源
-
-
-
活锁
-
没有阻塞但不满足条件无法继续执行
- 等待随机时间
-
-
饥饿
-
长期获取不到资源无法继续执行
- 公平分配
-
性能问题
-
Amdahl定律
-
使用无锁算法和数据结构
- ThreadLocal
- 写时复制
- 乐观锁
-
减小锁持有范围
-
细粒度锁
- 分段锁
- 读写锁
-
-
-
上下文切换
- 合理配置并发线程数
-
伪共享
-
原因
- 最小单位缓存行
-
解决方案
- 变量填充
-
-
衡量指标
- 吞吐量
- 延迟时间
- 并发量
线程生命周期
通用状态
-
初始状态
- 编程语言特有,操作系统层还没有真正创建
-
运行状态
- 运行中
-
可运行状态
- 可分配CPU执行
休眠状态
终止状态
Java线程状态
NEW(初始化)
RUNNABLE(可运行状态/运行状态)
-
BLOCKED(阻塞状态)
- synchronized
WAITING(无限时等待)
-
TIMED_WAITING(有限时等待)
- sleep
- wait()带超时参数
- join()带超时参数
- LockSupport.park()带超时参数
TERMINATED
并发工具类
Lock
-
和synchronized的区别
- 响应中断
- 支持超时
- 非阻塞式获取锁
Condition
Semaphore
ReadWriteLock和StampedLock
-
ReadWriteLock
- 读锁
- 写锁
- 锁不能升级,只能降级。升级会使写锁永久阻塞等待
- 写锁支持条件变量,读锁是不支持条件变量的
-
StampedLock
- 写锁
- 悲观读锁
- 乐观读
- 加锁成功会返回stamp,解锁需要传入stamp
- 性能更好
- 不可重入
- 不支持条件变量
- 使用readLock() 或writeLock() 时,不能使用阻塞线程的interrupt(),需要使用可中断的悲观读锁 readLockInterruptibly() 和写锁 writeLockInterruptibly()
CountDownLatch
- 解决一个线程等待多个线程的场景
- 计数器是不能循环利用
CyclicBarrier
- 一组线程之间互相等待
- 计数器是可以循环利用,自动重置
- 可以设置回调函数
并发容器类
-
List
- CopyOnWriteArrayList
-
Map
- ConcurrentHashMap
- ConcurrentSkipListMap
-
Set
- CopyOnWriteArraySet
- ConcurrentSkipListSet
-
Queue
-
.单端阻塞队列
- ArrayBlockingQueue
- LinkedBlockingQueue
- SynchronousQueue
- LinkedTransferQueue
- PriorityBlockingQueue
- DelayQueue
-
双端阻塞队列
- LinkedBlockingDeque
-
单端非阻塞队列
- ConcurrentLinkedQueue
-
双端非阻塞队列
- ConcurrentLinkedDeque
-
原子类
-
基本数据类型
- AtomicBoolean
- AtomicInteger
- AtomicLong
-
对象引用类型
- AtomicReference
- AtomicStampedReference
- AtomicMarkableReference
-
数组类型
- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray
-
对象属性更新器
- AtomicIntegerFieldUpdater
- AtomicLongFieldUpdater
- AtomicReferenceFieldUpdater
-
累加器
- DoubleAccumulator
- DoubleAdder
- LongAccumulator
- LongAdder
线程池
- ThreadPoolExecutor
- Executors
- Future
- FutureTask
- CompletableFuture
- CompletionService
- Fork/Join
并发设计模式
Immutability模式
- 基础类型包装类
Copy-on-Write模式
- 基础类型包装类
线程本地存储模式
- ThreadLocal
Guarded Suspension模式
- 等待唤醒机制
Balking模式
Thread-Per-Message模式
- 协程
- Fiber
Worker Thread模式
- Java线程池
两阶段终止模式
生产者-消费者模式
- Java线程池
- MQ
参考文档
JSR 133
XMind - Trial Version