并发编程是一个复杂的技术领域,微观上涉及到原子性问题、可见性问题和有序性问题,宏观则表现为安全性、活跃性以及性能问题。
安全性问题
其实本质上就是正确性,而正确性的含义就是程序按照我们期望的执行,不要让我们感到意外。
安全性方面:注意数据竞争和竞态条件。
数据竞争:当多个线程同时访问同一数据,并且至少有一个线程会写 这个数据的时候,如果我们不采取防护措施,那么就会导致并发 Bug。
竞态条件:程序的执行结果依赖线程执行的顺序。
活跃性方面
需要注意死锁、活锁、饥饿等问题。
死锁:线程会互相等待,而且会一直等待下去,在技术上的表现形式是线程永久地“阻塞”了。
活锁:有时线程虽然没有发生阻塞,但仍然会存在执行不下去的情况,这就是所谓的“活锁”。
饥饿:线程因无法访问所需资源而无法执行下去的情况。如果线程优先级“不均”,在 CPU 繁忙的情况下,优先 级低的线程得到执行的机会很小,就可能发生线程“饥饿”;持有锁的线程,如果执行的时 间过长,也可能导致“饥饿”问题。
性能方面
使用无锁的算法和数据结构提升性能或者减少锁持有的时间。
性能方面的度量指标有很多,有三个指标非常重要。
1. 吞吐量:指的是单位时间内能处理的请求数量。吞吐量越高,说明性能越好。
2. 延迟:指的是从发出请求到收到响应的时间。延迟越小,说明性能越好。
3. 并发量:指的是能同时处理的请求数量,一般来说随着并发量的增加、延迟也会增加。 所以延迟这个指标,一般都会是基于并发量来说的。
网友评论