《Java 并发编程实战》07 阅读笔记

84 阅读2分钟

作者认为,我们在设计并发程序的时候,要从宏观出发,重点关注它的安全性、活跃性以及性能。
安全性方面要注意数据竞争和竞态条件,活跃性方面需要注意死锁、活锁、饥饿等问题,性能方面虽然文末会给出两个方案,但还是要具体问题具体分析,根据特定的场景选择合适的数据结构和算法。

作者认为,线程安全本质上指的就是正确性,即程序会按照我们期望的执行,不会出现预料不到的结果。
而面对数据竞争和竞态条件问题,都可以采用互斥的技术方案。

活跃性问题,指的是某个操作无法执行下去。作者指出,常见的“死锁”就是一种典型的活跃性问题。此外,还有“活锁”和“饥饿”两种情况。

  • 活锁
    • 有时线程虽然没有发生阻塞,但仍然会存在执行不下去的情况,这就是所谓的“活锁”。
    • 解决“活锁”的方案很简单,尝试等待一个随机的时间就可以了。
  • 饥饿
    • 所谓“饥饿”指的是线程因无法访问所需资源而无法执行下去的情况。
    • 解决“饥饿”问题的方案,有三:一是保证资源充足,二是公平地分配资源,三就是避免持有锁的线程长时间执行。

作者给出了两个方案来解决性能方面的问题:

  • 使用无锁的算法和数据结构
  • 减少锁持有的时间

同时还给出了三个性能方面的指标:

  • 吞吐量:指的是单位时间内能处理的请求数量。吞吐量越高,说明性能越好。
  • 延迟:指的是从发出请求到收到响应的时间。延迟越小,说明性能越好。
  • 并发量:指的是能同时处理的请求数量,一般来说随着并发量的增加、延迟也会增加。