代码整洁_并发编程

对象是过程的抽象,线程是调度的抽象。
编写整洁的并发程序很难


1. 为什么要并发

并发是一种解耦策略。帮助我们把做什么(目的)和何时(时机)做分
解开。 解耦目的与时机能明显地改善应用程序的吞吐量和结构。
并发:
并发会在性能和编写额外代码上添加一些开销
正确的并发是复杂的,即便对于简单的问题也是如此。
并发缺陷并非总能重现
并发常常需要对设计策略的根本性修改

2 并发防御原则:

  • 2.1 单一权责原则(SRP):
    方法/类/组件应当只有一个修改的理由
    并发设计自身足够复杂到成为修改的理由,所以也该从其他代码中分离出来。
    考虑问题:
    并发相关代码有自己的开发、修改和调优生命周期
    开发相关代码有自己要对付的挑战,和非并发相关代码不同,会更困难
    没有外在影响,写的不好的并发代码出错也会很多。
    建议:
    分离并发相关代码与其他代码。
  • 2.2 限制数据作用域
    采用synchronized关键字在代码中保护一块使用共享对象的临界区
  • 2.3 使用数据复本
    避免共享数据的好方法之一避免共享数据。 只读方式创建复本,然后收集复本合并。
  • 2.4 线程应尽可能地独立
    建议:
    尝试将数据分解到可被独立线程(可能在不同处理器上)操作的独立子集。

3 使用java 线程库。

使用executor框架执行无关任务。 尽可能使用非锁定解决方案
建议:
检读可用的类: 对于Java,掌握java.util.concurrent、 java.util.concurrent.atomic、 java.util.concurrent.locks,
ReentrantLock     可在一个方法中获取、在另一个方法中释放的锁
Semaphore     经典的“信号”的一种实现,有计数器的锁
CountDownLatch    在释放所有等待的线程之前,等待指定数量事件发生的锁,这样,所有线程都平等地几乎同时启动。

4 了解执行模型

基础定义:
限定资源, 互斥, 线程饥饿, 死锁, 活锁
执行模型:
生产者-消费者模型 (之间的队列就是一种限定资源)
读者-作者模型 宴席哲学家
如何找到必须锁定的代码区域并锁定

5 警惕同步方法之间的依赖

避免使用一个共享对象的多个方法。但有时必须使用一个共享代码的多个方法,有三种写对代码的手段:
- 基于客户端的锁定
客户端代码在调用第一个方法前锁定服务器,确保锁的范围覆盖了调用使用最后一个方法的代码
- 基于服务端的锁定
在服务器内创建锁定服务器端的方法,调用所有方法,然后解锁。让客户端调用新方法。
- 适配服务端
创建执行锁定的中间层。这是一种基于服务器的锁定的例子,但不修改原始服务端代码。

6. 保持同步区域微小

7. 尽早考虑关闭问题,尽早令其工作正常。

8. 测试线程代码。

建议:
不要将系统错误归咎于偶发事件
不要同时追踪非线程缺陷和线程缺陷。确保代码在线程之外可工作。
编写可拔插的线程代码,这样就能在不同配置环境下运行
尽早并经常地在所有目标平台上运行程序代码
两种装置代码的方式: 硬编码 , 自动化(使用Aspect-Oriented Framework, CGLIB, ASM等工具来编程来装置代码)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章