第四章 并行程序优化
4.1 并行程序设计模式
4.2 JDK多任务执行框架
4.3 JDK并发数据结构
4.4 并发控制方法
4.5 锁的性能和优化
4.6 无锁的并行计算
1.非阻塞同步避免了基于锁的同步的缺陷,无锁算法没有锁竞争带来的系统开销,也没有线程间频繁调度带来的开销。
CAS算法:包含3个参数CAS(v,e,n)。V表示要更新的变量,E表示预期值,N表示新值
2.JDK的java.util.concurrent.atomic包下,有一组使用无锁算法实现的原子操作类,如AtomicInteger/AtomicIntegerArray/AtomicLongArray等,
分别包装了对整数、整数数组、长整形数组等的多线程安全操作。
如:
public class AtomicTest { public static final int MAX_THREADS=3; public static final int TASK_COUNT=3; public static final int TARGET_COUNT=10000; private AtomicInteger account=new AtomicInteger(0);//无锁的原子操作数量 private int count=0; //有锁的加法 private synchronized int add() { return count++; } //有锁的操作 private synchronized int getCount() { return count; } //实现有锁操作的内部类 public class SynchThread implements Runnable{ protected String name; protected long starttime; AtomicTest out; public SynchThread(AtomicTest o,long starttime) { out=o; this.starttime=starttime; } @Override public void run() { int v=out.add();//有锁的加法 while (v<TARGET_COUNT) { v=out.add();//达到目标值前,不停的循环 } long endtime=System.currentTimeMillis();//系统当前时间 精确到ms System.out.println("SynchThread spend:"+(endtime-starttime)+"ms"); } } //实现原子操作的内部类 public class AtomicThread implements Runnable{ protected long starttime; public AtomicThread(long starttime){ this.starttime=starttime; } @Override public void run() { int v=account.incrementAndGet(); while(v<TARGET_COUNT){ v=account.incrementAndGet(); } long endtime=System.currentTimeMillis(); System.out.println("AtomicThread spend:"+(endtime-starttime)+"ms"); } } /** * JUnit方法测试 * @throws InterruptedException */ @Test public void testAtomic() throws InterruptedException { ExecutorService exe=Executors.newFixedThreadPool(MAX_THREADS);//初始化三个线程 long starttime=System.currentTimeMillis(); AtomicThread atomic=new AtomicThread(starttime); for(int i=0;i<TARGET_COUNT;i++){ exe.submit(atomic);//提交三个线程开始工作 } Thread.sleep(1000);//重新分配 } // @Test public void testSynch() throws InterruptedException { ExecutorService exe=Executors.newFixedThreadPool(MAX_THREADS); long starttime=System.currentTimeMillis(); SynchThread synch=new SynchThread(this,starttime); for(int i=0;i<TARGET_COUNT;i++){ exe.submit(synch); } Thread.sleep(1000); //检测线程池是否关闭 System.out.println(exe.isTerminated()); } }
3.Amino框架。使用无锁算法的主要缺点在于需要在应用层处理线程间的冲突问题。Amino提供了可用于线程安全的、基于无锁算法的一些数据结构,同时内置了一些多线程调度模式。
4.Amino集合。
5.Amino树。
6.Amino图。
7.Amino简单调度模式,最典型的是Master-Worker模式。Amino提供了两套实现,即静态和动态实现。
4.7 协程
1.线程是对进程的进一步分割,协程可以理解为对线程的进一步分割。
在Lua语言中对协程做了很好的实现。
2.Java原生语言不支持协程,Kilim是一个流行的协程框架。
使用协程,可以让系统以更低的成本,支持更高的并行度。