第一章 Why 并行?
并行计算能应用的两个场景:图像处理、服务端编程。
几个概念
同步(Synchronous)和异步(Asynchronous)
并发(Concurrency)和并行(parallelism)
临界区
阻塞(Blocking)和非阻塞(Non-blocking)
死锁、饥饿、活锁
并发级别
1.阻塞; 2.无饥饿; 3.无障碍; 4.无锁; 5.无等待
Amdahl定律和Gustafson定律:研究并行所能带来的性能的提升程度。
JMM(Java内存模型)
1.原子性;2.可见性;3.有序性;
第二章 Java并行基础
线程状态:
New、Runnable、Blocked、Waiting、Timed_Waiting、Terminated
终止线程不用stop();
线程中断:
public void Thread.interrupt(); //中断线程
public boolean Thread.isInterrupted(); //判断是否中断
public static boolean Thread.interrupted(); //判断是否中断,并清楚当前中断状态
wait()和notify():
存在于Object类;
必须包含在对应的synchronzied语句中,并且都要首先获得目标对象的一个监视器。
挂起(suspend)和继续执行(resume),和stop()一样,不再使用。
等待线程结束(join)和谦让(yield)
volatile 关键字,可见性,不保证原子性;
线程组、守护线程(Daemon)、线程优先级(priority)
synchronized 关键字 :1.指定加锁对象;2.直接作用于实例方法;3.直接作用于静态方法。
第三章 JDK并发包
重入锁 java.util.concurrent.locks.ReentrantLock
lock.lock()、lock.unlock()、lock.lockInterruptibly()(中断响应)、lock.tryLock()(限时等待)、公平锁、
根据系统的调度,一个线程会倾向于再次获取已经持有的锁,这种分配方式高效,但无公平性。
Condition条件,搭配重入锁使用。
await()、singal()、awaitUninterruptibly()(在等待中不响应中断)
信号量(Semaphore)
acquire()、tryAcquire()、release()
ReadWriteLock 读写锁
倒计时器 CountDownLatch
countDown()、await()
循环栅栏 CyclicBarrier 凑齐一批,计数器归零,执行某一动作
线程池
Executor框架 newFixedThreadPool、newSingleThreadExecutor、newCachedThreadPool、newScheduledThreadPool...
计划任务 scheduleAtFixedRate、scheduleWithFixedDelay
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler hanler)
corePoolSize: 线程池中的线程数量;
maximumPoolSize: 线程池中的最大线程数量;
keepAliveTime: 当线程池中线程数量超过corePoolSize时,多余的空闲线程的存活时间。
unit: keepAliveTime的单位
workQueue:任务队列,用于保存被提交但未被执行的线程;
(直接提交队列、有界任务队列、无界的任务队列、优先任务队列)
threadFactory:线程工厂,用于创造线程,一般默认;
handler:拒绝策略;
(AbortPolicy、CallerRunsPolicy、DiscardOledestPolicy、DiscardPolicy)
扩展线程池 beforeExecute()、afterExecute()、terminated()
优化线程池线程数量
Nthreads = Ncpu * Ucpu * ( 1 + W / C ) = cpu数量*目标cpu使用率*(1+等待时间与计算时间的比率)
submit() vs execute()
并发集合 java.util.concurrent
ConcurrenHashMap、CopyOnWriteArrayList、ConcurrentLinkedQueue、BlockingQueue、ConcurrentSkipListMap(跳表)
第四章 锁的优化
有助于提高“锁”性能的几点建议:
1.减小锁持有时间;
2.减小锁粒度;(例如hashmap,分成16块,分块加锁)
3.读写分离锁来代替独占锁;(读多写少的情况下)
4.锁分离;(例如LinkedBlockingQueue,把take()和put()分离)
5.锁粗化;(主要值避免循环内反复申请锁)
Java虚拟机对锁的优化:
1.锁偏向;
2.轻量级锁;
3.自旋锁;
4.锁消除;
ThreadLocal:
ThreadLocalMap 保存了以每个线程为key的KV,类似HashMap;
在为每个线程各分配一个SimpleDateFormat、Ramdom等时能提高性能。
无锁
比较变换(CAS):一种与众不同的并发策略。
CAS(V,E,N)。V表示要更新的变量,E表示预期值,N表示新值;仅当V值等于E值时,才会将V的值设为N;否则什么都不做。最后都返回当前V值。
AtomicInteger、Unsafe类、AtomicReference、AtomicStampedReference(带时间戳的对象引用)、AtomicIntegerArray、AtomicIntegerFieldUpdater(让普通变量也享受原子操作)
无锁的Vector实现。(较难,没看懂)
SynchronousQueue的实现。
避免死锁:无锁函数、重入锁的中断或限时等待...
网友评论