【多线程】实战Java高并发程序设计

第一章 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 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的实现。

避免死锁:无锁函数、重入锁的中断或限时等待...

你可能感兴趣的:(【多线程】实战Java高并发程序设计)