“对象是过程的抽象,线程时调度的抽象。”——James O Coplien
为什么要并发?
并发是一种解耦策略。它帮助我们把做什么(目的)和何时(时机)做分解开。解耦的目的和时机能明显地改进应用程序的吞吐量和结构。从结构角度来看,应用程序看起来像是许多协同工作的计算机,而不是一个大循环。
并发防御机制:
(1)单一权责原则SRP:分离并发相关代码和其他代码
(2)推论:限制数据作用域(谨记数据封装;严格限制对可能被共享的数据的访问)
(3)推论:使用数据复本
(4)推论:线程应尽可能地独立(尝试将数据分解到可悲独立线程(可能在不同处理器上)操作的独立子集)
了解执行模型:
(1)生产者-消费者模型
(2)读者-作者模型
(3)宴席哲学家
警惕同步方法之间的依赖:
同步方法之间的依赖会导致并发代码中的狡猾缺陷,因此应当避免使用一个共享对象的多个方法。
若必须使用一个共享对象的多个方法,有3种写代码手段:
(1)基于客户端的锁定
(2)基于服务端的锁定
(3)适配服务端
保持同步区域的微小
很难编写正确的关闭代码:
尽早考虑关闭问题,尽早令其工作正常。
测试线程代码:
(1)将伪失败看作可能的线程问题:不要将系统错误归咎于偶然事件
(2)先使非线程代码可工作:不要同时追踪非线程缺陷和线程缺陷
(3)编写可插拔的线程代码:可以在不同的配置环境下运行
(4)编写可调整的线程代码
(5)运行多于处理器数量的线程
(6)在不同平台上运行:尽早并经常在所有目标平台上运行线程代码
(7)装置试错代码:找到更多可能出现的错误
(8) 装置代码——硬编码:手工向代码中插入wait()、sleep()、yield()、priority()的调用。
(9)装置代码——自动化:使用工具来编程实现装置代码,如ASM
遵守SRP —> 了解并发问题的可能原因 —> 学习类库,了解基本算法 —> 学习如何找到必须锁定的代码区域并锁定之
—> 问题会跳出来 —> 写装置代码,提高发现错误代码的机会