如何用面向对象的思想来写好并发程序?
1)我们设计并发程序需要明确那三点呢?
-
把我们共享变量封装起来,提供一定接口给外界访问。
-
明确我们共享变量之间的约束条件
-
指定访问共享变量的策略
2)该如何去封装我们的共享变量呢?
比方说我要封装一个计数器的共享变量count,那就是属性私有,get,addOne方法,并且方法用synchronized修饰 一下。
class Counter {
private int count;
synchronized int get() {
return this.count;
}
synchronized int addOne() {
return ++count;
}
}
3)所有的 共享变量我都需要去考虑并发问题吗?
-
并不是所有的共享变量都需要考虑并发的问题。比如我的信用卡,有卡号 ,姓名,性别,身份证,余额,透支额度。像卡号,姓名,性别,身份证这些都是不会改变的变量,那我设计的时候直接加final修饰,告诉后面接手的兄弟,这个变量我考虑过并发问题了。
4)明确共享变量之间的约束条件怎么理解?
-
现在我设计一个线程池类,下限为2,上限为7。A线程把下限从2改到10,B线程把上限从7降到5。很显然我们的下限是需要小于我们的上限的,这是一个约束条件,但是如果A和B同时发生的话,那最后下限是10,上限是5。不符合我们的约束。
public class ThreadPool {
// 上限
private final AtomicLong upper =
new AtomicLong(0);
// 下限
private final AtomicLong lower =
new AtomicLong(0);
// 设置上限
void setUpper(long v){
// 检查参数合法性
if (v < lower.get()) {
throw new IllegalArgumentException();
}
upper.set(v);
}
// 设置下限
void setLower(long v){
// 检查参数合法性
if (v > upper.get()) {
throw new IllegalArgumentException();
}
lower.set(v);
}
// 省略其他业务代码
}
4.1)怎样解决我们上面因为并发而导致约束条件被破坏的问题?
-
加把锁就可以:setUpper() 跟 setLower() 都加上 "synchronized" 关键字。
5)怎样去制订一个合理的并发策略?
-
使用成熟的,现成的工具类。
-
除非万不得已,否则不使用低级的同步原语synchronized,Lock,semphore。要用就用高级的像读写锁啊之类的。
-
不要一开始就过度设计,因为可能压根就没有这么大的并发量。
6)制订并发访问策略有哪几种方案?
-
避免共享:线程本地存储,为每个任务分配独立线程。
-
管程和其它并发工具:万能的是管程,但是细节雕琢上还是并发工具更胜一筹(读写锁,并发容器都是很不错的)
-
不变模式(java不常用):了解即可
posted on 2022-03-22 14:38 Love&Share 阅读(36) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY