并发01_并发设计模式
2023-03-17 10:33:28 0 举报
AI智能生成
并发设计模式总结
作者其他创作
大纲/内容
两阶段终止模式
将终止过程分成两个阶段
第一个阶段主要是线程 T1 向线程 T2发送终止指令
第二阶段则是线程 T2响应终止指令
关键点
一个是仅检查终止标志位是不够的
线程的状态 可能处于休眠态
另一个是仅检查线程的中断状态也是不够的
我们依赖的第三方类库很 可能没有正确处理中断异常
在捕获到 Thread.sleep() 方法抛出的中断异常 后,没有重新设置线程的中断状态
使用场景
1. 安全地终止线程,比如释放该释放的资源
2. 要确保终止处理逻辑在线程结束之前一定会执行时,可使用该方法
Immutability模式
本质上都是为了避免共享
使用时需要注意Immutability模式的属性的不可变性
Copy-on-Write模式需要注意拷贝的性能问题
Thread-Specific Storage模式需要注意异步执行问题
让共享变量只有 读操作,而没有写操作
对象一旦被创建之后,状态就不再发生变化
是变量一旦被赋值,就不允许修改了(没有写操作)
没有修 改操作,也就是保持了不变性
实现
将一个类所有的属性都设置成 final 的,并且只允许存在只读方法,那么这个类基本上就具 备不可变性了。
更严格的做法是这个类本身也是 final 的,也就是不允许继承
更严格的做法是这个类本身也是 final 的,也就是不允许继承
类和属性都是 final
所有方法均是只读的
注意事项
对象的所有属性都是 final 的,并不能保证不可变性
不可变对象也需要正确发布
Copy-on-Write模式
写时复制
不可变对象的写操作往往都是使用 Copy-on-Write 方法解决的
缺点
消耗内存,每次修改都需要复制一个新的对象出来
只适合读多写少
应用场景
CopyOnWriteArrayList 和 CopyOnWriteArraySet
是无锁的,所以将读操作的性能发挥到了极致
Unix 的操作系统中创建进程的 API 是 fork()
在函数式编程领域
函数式编程的基础是不可变性 ,所以函数式编程里面所有的修改操作都需要 Copy-on-Write 来解决
RPC框架,服务注册中心,会利用Copy-on-Write设计思想维护服务路由表
Thread-Specific Storage 模式
即使只有一个入口,也会在内部为 每个线程分配特有的存储空间的模式
本质上是一种避免共享的方案,由于没有共享,所以自然也就没有并发 问题
应用场景
SimpleDateFormat 不是线程安全的,在并发场景下使用它可用 ThreadLocal 来解决
注意点
在线程池中使用ThreadLocal 需要避免内存泄漏和线程安全的问题
Guarded Suspension模式
是通过让线程等待来保护实例的安全性,即守护-挂起模式
有一个结果需要从一个线程传递到另一个线程,让他们关联同一个 GuardedObject
如果有结果不断从一个线程到另一个线程那么可以使用消息队列
JDK 中,join 的实现、Future 的实现,采用的就是此模式
因为要等待另一方的结果,因此归类到同步模式
应用场景
多线程环境下多个线程访问相同实例资源,从实例资源中获得资源并处理
实例资源需要管理自身拥有的资源,并对请求线程的请求作出允许与否的判断
Balking模式
如果现在不适合执行这个操作,或者没必要执行这个操 作,就停止处理,直接返回
常用于一个线程发现另一个线程已经做了某一件相同的事,那么本线程 就无需再做了,直接结束返回
常见的应用场景
sychronized轻量级锁膨胀逻辑, 只需要一个线程膨胀获取monitor对象
DCL单例实现
服务组件的初始化
Thread-Per-Message 模式
属于多线程分工模 式
为每个任务分配一个独立的线程
需要注意线程的创建,销毁以及是否会导致OOM
应用场景
网络编程里服务端的实现,服务端 为每个客户端请求创建一个独立的线程,当线程处理完请求后,自动销毁
Worker Thread模式
需要注意死锁问题,提交的任务之间不要有依赖性
可以直接使用线程池来实现
生产者 - 消费者模式
核心是一个任务队列
生产者线程生产任务,并将任务添加到任务 队列中,而消费者线程从任务队列中获取任务并执行
优点
支持异步处理
解耦
可以消除生产者生产与消费者消费之间速度差异
过饱问题解决方案
在实际生产项目中会有些极端的情况,导致生产者/消费者模式可能出现过饱的问题
单位时间内,生产者生产的速度大于消费者消费的速度,导致任务不断堆积到阻塞队列中
场景一
消费者每天能处理的量比生产者生产的少;如生产者每天1万条,消费者每天只能消费5千条
解决办法:消费者加机器
原因:生产者没法限流,因为要一天内处理完,只能消费者加机器
场景二
消费者每天能处理的量比生产者生产的多。系统高峰期生产者速度太快,把队列塞爆了
解决办法:适当的加大队列
原因:消费者一天的消费能力已经高于生产者,那说明一天之内肯定能处理完,保证高峰期别把队列塞满就好
场景三
消费者每天能处理的量比生产者生产的多。条件有限或其他原因,队列没法设置特别大。系统高峰期生产者速度太快,把队列塞爆了
解决办法:生产者限流
原因:消费者一天的消费能力高于生产者,说明一天内能处理完,队列又太小,那只能限流生产者,让高峰期塞队列的速度慢点
0 条评论
下一页
为你推荐
查看更多