Java并发编程实战
2021-11-28 20:53:53 43 举报
AI智能生成
Java并发编程实战
作者其他创作
大纲/内容
CPU-内存-IO 速度差异
来源
线程A对CPU缓存的操作,线程B从主存获取最新
定义
可见性1.png
可见性
线程切换
原子性6.png
count++
不被中断的CPU指令
原子性
编译器优化
eg.不安全的单例
有序性
3大问题
缓存-->可见性
编译器优化-->有序性
缓存&编译器优化
JVM按需禁用
volatile
synchronized
final
程序的顺序性规则
volatile 变量规则
传递性
Java:synchronized
管程:通用的同步原语
管程中锁的规则
线程 start() 规则
线程 join() 规则
Happens-Before 规则
方法
解决
Java内存模型
一个锁保护多个资源
用不同的锁对受保护资源进行精细化管理,能够提升性能
细粒度锁
this->共享object->Class
覆盖所有资源
互斥锁
一组互相竞争资源的线程因互相等待,导致“永久”阻塞的现象。
互斥,共享资源 X 和 Y 只能被一个线程占用;
占有且等待,线程 T1 已经取得共享资源 X,在等待共享资源 Y 的时候,不释放共享资源 X;
不可抢占,其他线程不能强行抢占线程 T1 占有的资源;
循环等待,线程 T1 等待线程 T2 占有的资源,线程 T2 等待线程 T1 占有的资源,就是循环等待。
4条件同时即死锁
可以一次性申请所有的资源
破坏占用且等待条件
占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源
破坏不可抢占条件
可以靠按序申请资源来预防
破坏循环等待条件
破坏任意一个条件
如何预防死锁
死锁
锁 Lock
“等待-通知”
安全性问题
活跃性问题
性能问题
关注问题
互斥
同步
MESA模型
管程
Java线程
基础理论
synchronized--死锁问题
能够响应中断
支持超时
非阻塞地获取锁
互斥锁设计
再造管程的理由
volatile 的 Happens-Before 规则
如何保证可见性
线程可以重复获取同一把锁
可重入锁
唤醒的策略就是谁等待的时间长
公平锁
随机唤醒
非公平锁
公平锁与非公平锁
永远只在更新对象的成员变量时加锁
永远只在访问可变的成员变量时加锁
永远不在调用其他对象的方法时加锁
最佳实践
Lock
利用两个条件变量实现阻塞队列
同步:调用方需要等待结果
异步:调用方不需要等待结果
同步与异步
调用方创建一个子线程,在子线程中执行方法调用
异步调用(调用方)
方法实现的时候,创建一个新的线程执行主要逻辑,主线程直接 return
异步方法(实现方)
异步实现
Condition
Lock和Condition
允许多个线程同时读共享变量
只允许一个线程写共享变量
如果一个写线程正在执行写操作,此时禁止读线程读共享变量
什么是读写锁
快速实现一个缓存
实现缓存的按需加载
锁的升级
锁的降级
读写锁的升级与降级
ReadWriteLock
ReadWriteLock 的写锁
写锁
ReadWriteLock 的读锁
悲观读锁
版本对比(无锁)
乐观读
3种模式
StampedLock 不支持重入
悲观读/写锁都不支持条件变量
readLockInterruptibly()
writeLockInterruptibly()
一定不要调用中断操作,除非调用可中断的读/写锁
注意事项
StampedLock
CountDownLatch:一个线程等待多个线程
CyclicBarrier:一组线程之间互相等待
CountDownLatch和CyclicBarrier
Semaphore-信号量
Exchanger-交换者
并发工具
CopyOnWrite:写操作时候拷贝一份
读多写少,容忍读写不一致
CopyOnWriteArrayList 迭代器是只读的,不支持增删改
适用场景
CopyOnWriteArrayList
List
key无序
ConcurrentHashMap
key有序
ConcurrentSkipListMap
Map
ConcurrentSkipListSet
CopyOnWriteArraySet
Set
BlockingDeque
BlockingQueue
ConcurrentLinkedQueue
ConcurrentLinkedDeque
Queue
并发容器
AtomicBoolean
AtomicInteger
AtomicLong
基本数据类型
AtomicReference
版本号解决ABA问题
AtomicStampedReference
boolean值解决ABA问题
AtomicMarkableReference
引用类型
AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray
数组
AtomicIntegerFieldUpdater
AtomicLongFieldUpdater
AtomicReferenceFieldUpdater
对象属性更新器
DoubleAccumulator
DoubleAdder
LongAccumulator
LongAdder
累加器
原子类
线程是一个重量级的对象,应该避免频 繁创建和销毁
缘由
生产者-消费者模式
原理
线程池保有的最小线程数。
corePoolSize
线程池创建的最大线程数。
maximumPoolSize
> corePoolSize的线程,空闲指定时间后销毁
keepAliveTime & unit
设置有界队列
工作队列
workQueue
自定义如何创建线程
threadFactory
提交任务的线程自己去执行该任务。
CallerRunsPolicy
默认的拒绝策略,会 throws RejectedExecutionException。
AbortPolicy
直接丢弃任务,没有任何异常抛出。
DiscardPolicy
丢弃老的任务。
DiscardOldestPolicy
拒绝策略
handler
参数
execute(Runnable command)
无返回结果
没有返回值,Future仅仅用来判断任务已经结束了
Future<?> submit(Runnable task)
Future.get()获取返回值
<T> Future<T> submit(Callable<T> task)
result用于主/子线程间共享数据
带返回结果
执行任务
Executor与线程池
简单并行任务,线程池 + Future
取消任务
boolean cancel(boolean mayInterruptIfRunning)
判断任务是否已取消
boolean isCancelled()
判断任务是否已结束
boolean isDone()
获取任务执行结果
get()
获取任务执行结果(超时内)
接口
FutureTask(Callable<V> callable)
构造器
eg.
FutureTask.png
FutureTask
并发-并行.png
Future
任务间有聚合关系,AND 或 OR
CompletableFuture
CompletionService
Fork/Join
线程池与异步
Immutability模式
Copy-on-Write模式
使用示例
实现原理
线程池下的问题:内存泄漏
ThreadLocal
Guarded Suspension模式
Balking模式
Thread-Per-Message模式
Worker Thread模式
两阶段终止模式
协程
CSP模型
不保证100%发送
不保证消息送达的顺序和发送的顺序是一致
不保证消息会被百分百处理
Actor 模型
软件事务内存
并发模式
Java并发编程实战
0 条评论
回复 删除
下一页