1、安全性问题
就是线程安全问题,除了加锁还有就是不要共享变量,在18年我接手的一个照片管理后台(AI模块管理)班牌要来获取照片,每个班牌都要获取,每个班牌都会在服务端生成一个压缩包,开始的时候就只有一个唯一的压缩包,每个班牌都公用,就会导致第一个班牌生成了压缩包,第二个班牌去访问的时候错拿了,如果没有并发还好,并发的时候就坑了,然后我改成了每个班牌在后台都有一个文件夹,就是不让他发生竞争 ,其实这个思想和ThreadLocal是一样的。就是多个线程不共享变量。
2、活跃性问题
活锁
就是俩个线程都互相谦让一把锁
解决办法
饥饿
解决办法
公平锁
3、性能问题
有个阿姆达尔(Amdahl)定律,代表了处理器并行运算之后效率提升的能力,它正好可以解决这个问题,具体公式如下
公式里的 n 可以理解为 CPU 的核数,p 可以理解为并行百分比,那(1-p)就是串行百分比了,也就是我们假设的 5%。我们再假设 CPU 的核数(也就是 n)无穷大,那加速比 S 的极限就是 20。也就是说,如果我们的串行率是 5%,那么我们无论采用什么技术,最高也就只能提高 20 倍的性能。
性能一般包括三个方面
- 吞吐量
- 延迟
- 并发量
kafka也是这么衡量的。
课后思考
void addIfNotExist(Vector v,
Object o){
if(!v.contains(o)) {
v.add(o);
}
}
答案
Vector实现线程安全是通过给主要的写方法加了synchronized,类似contains这样的读方法并没有synchronized,该题的问题就出在不是线程安全的contains方法,两个线程如果同时执行到if(!v.contains(o)) 是可以都通过的,这时就会执行两次add方法,重复添加。也就是老师说的竞态条件。