使用本地变量
尽量使用本地变量,而不是创建一个类或实例的变量。
使用不可变类
String、Integer等。不可变类可以降低代码中需要的同步数量。
最小化锁的作用域范围:S=1/(1-a+a/n)
a:并行计算部分所占比例
n:并行处理结点个数
S:加速比
当1-a等于0时,没有串行只有并行,最大加速比 S=n
当a=0时,只有串行没有并行,最小加速比 S = 1
当n→∞时,极限加速比 s→ 1/(1-a)
例如,若串行代码占整个代码的25%,则并行处理的总体性能不可能超过4。
该公式称为:"阿姆达尔定律"或"安达尔定理"。
使用线程池的Executor,而不是直接 new Thread 执行
创建一个线程的代价是昂贵的,如果要创建一个可伸缩的Java应用,那么你需要使用线程池。
宁可使用同步也不要使用线程的wait和notify
从Java1.5以后,增加了许多同步工具,如:CountDownLatch、CyclicBarrier、Semaphore等,应该优先使用这些同步工具。
使用BlockingQueue实现生产-消费模式
阻塞队列不仅可以处理单个生产、单个消费,也可以处理多个生产和消费。
使用并发集合而不是加了锁的同步集合
Java提供了下面几种并发集合框架:
ConcurrentHashMap、CopyOnWriteArrayList、CopyOnWriteArraySet、ConcurrentLinkedQueue 、ConcurrentLinkedDeque等(相关介绍请见Java 并发编程(九)并发集合框架)
使用Semaphore创建有界的访问
为了建立稳定可靠的系统,对于数据库、文件系统和socket等资源必须要做有机的访问,Semaphore可以限制这些资源开销的选择,Semaphore可以以最低的代价阻塞线程等待,可以通过Semaphore来控制同时访问指定资源的线程数。
宁可使用同步代码块,也不实用同步的方法
主要针对synchronized关键字。使用synchronized关键字同步代码块只会锁定一个对象,而不会将整个方法锁定。如果更改共同的变量或类的字段,首先应该选择的是原子型变量,然后使用volatile。如果需要互斥锁,可以考虑使用ReentrantLock。
避免使用静态变量
静态变量在并发执行环境下会制造很多问题,如果必须使用静态变量,那么优先是它成为final变量,如果用来保存集合collection,那么可以考虑使用只读集合,否则一定要做特别多的同步处理和并发处理操作。