Java并发编程
5.1、forkjoinTask、forkjoinPool 6
十、Callable、Future和FutureTask 7
第一章、基础
一、线程基础
1.1、CPU核心数和线程数的关系
一个CPU上有多个处理器(双核、三核、四核 … …)
CPU核心数与线程数的关系为一对一的关系
1.2、CPU时间片轮转机制
上下文切换
1.3、什么是进程和线程
进程:一个程序运行中资源分配的最小单位
线程:CPU调试的最小单位,共享进程中的资源(必须依附进程)
1.4、澄清并行和并发
并行:如 高速路
并发:有时间概念
1.5、高并发编程的意义
好处:
充分利用CPU的资源
加快用户响应时间
程序功能(模块化、异步化)
注意事项:
线程的安全性(资源共享,如变量)
二、认识Java里的线程
2.1、新启线程的方式
类Thread
接口Runnable
接口Callable
示例:NewThread.java
2.2、停止线程
Stop:强制终结线程,无法保证这线程资源被正常释放;
suspend:占着资源进入睡眠状态,容易进入死锁;
示例1:StopThread.java
Interrupt:去终断一个线程【只是将中断标志位置为true】
IsInterrupted:检查线程是否要求被终断
Static方法interrupted:检查线程是否要求被终断,并将终断的标志位改为false
示例2:EndThread.java EndRunnable.java
2.3、阻塞方法(线程中断)
阻塞方法中抛出InterruptedException异常后,如果需要继续中断,需要手动再中断一次
示例1:HasInterrputException.java
三、线程常用方法和线程的状态
3.1、Yield
Yield:让当前线程让出CPU时间,os依然可以选中当前线程
3.2、Join:
示例:UseJoin.java
3.3、线程的优先级:
3.4、守护线程:
endThread.setDaemon(true);//设置为守护线程
endThread.start();//setDaemon 一定要在 start方法之前
【守护线程中finally不一定起作用】
示例:DaemonThread.java
第二章、线程协作通信
四、线程间的共享
4.1、ThreadLocal的使用
示例1:UseThreadLocal.java
4.2、synchronized内置锁
用处
对象锁
类锁
示例:SynClassAndInstance.java
4.3、volatile关键字
最轻量的同步机制
示例:UseVola.java
4.4、等待和通知
Wait:
Notify/notifyAll:
等待超时模式
Notify和notifyAll应该用谁:
示例:TestWN.java
4.5、join方法
示例1:UseJoin.java
4.6、关键方法对锁的影响
yield、sleep、wait、notify等方法对锁有何影响
第三章、并发工具类
五、Fork/Join 分而治之
5.1、forkjoinTask、forkjoinPool
5.2、使用示例
1、RecursiveAction 示例:FindDirsFiles.java
2、RecursiveTask<T> 示例:SumDirsFiles.java 带返回值
六、CountDownLatch
6.1、使用示例
1、允许一个或多个线程等待其他线程完成操作后继续自己的操作,类似加强版join
2、CountDownLatch用法,共5个初始化子线程,6个闭锁扣除点,扣除完毕后,主线程和业务线程才能继续执行
3、示例:UseCountDownLatch.java
七、CyclicBarrier
7.1、使用示例
1、让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
2、可以在一组线程到达屏障时,优先执行某个操作,方便处理更复杂的业务场景
演示CyclicBarrier用法,共5个子线程,他们全部完成工作后,交出自己结果,再被统一释放去做自己的事情,而交出的结果被另外的线程拿来拼接字符串
3、示例:UseCyclicBarrier.java
八、Semaphore
8.1、使用示例
1、用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源
2、常用于做流量控制,特别是公用资源有限的应用场景,比如数据库连接池,有界缓存等。
3、演示Semaphore用法,一个数据库连接池的实现
4、示例:DBPoolSemaphore.java
九、Exchange的应用场景和实战
9.1、使用示例
1、用于进行线程间的数据交换。它提供一个同步点,在这个同步点,两个线程可以交换彼此的数据。
2、示例:UseExchange.java
十、Callable、Future和FutureTask
Callable 示例:
Future 示例:UseFuture.java
futureTask 示例:
10.1、Future接口用来表示异步计算的结果
10.2、FutureTask类实现了future接口
第四章、线程安全
十一、怎么才能做到线程安全
无状态、让类不可变、volatile、加锁、CAS … …
示例:PayCompany.java
十二、更多线程不安全问题
有哪些死锁、怎么解决死锁、其他死锁问题
活锁、线程饥饿、性能
示例:NormalDeadLock.java
十三、显示锁
13.1、lock使用
1、lock接口和synchronized
2、lock接口中的核心方法:lock、unlock、trylock
3、示例:LockCase.java
十四、CAS(Compare And Swap)
14.1、CAS的原理、CAS的问题
1、Jdk中相关原子操作类的使用:
更新基本类型类:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
更新数组类:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray
更新引用类型:AtomicReference,AtomicMarkableReference,AtomicStampedReference
原子更新字段类:
AtomicReferenceFieldUpdater,AtomicIntegerFieldUpdater,AtomicLongFieldUpdater
2、示例:UseAtomicStampedReference.java
第五章、线程池
十五、为什么要用线程池
15.1、线程池分类
1、ThreadPoolExecutor(*)
2、FixedThreadPool
3、SingleThreadExecutor
4、CachedThreadPool
5、WorkStealingPool(JDK7以后)
6、ScheduledThreadPoolExecutor
7、示例:ScheduledCase.java
第六章、并发容器
十六、ConcurrentHashMap
为什么要用ConcurrentHashMap,它是如何实现的?
十七、更多的并发容器
ConcurrentSkipListMap 和 ConcurrentSkipListSet 了解什么是SkipList?
ConcurrentLinkedQueue
CopyOnWriteArrayList
CopyOnWriteArraySet
十八、阻塞队列
什么是阻塞队列
概念、常用方法、常用阻塞队列
阻塞队列的实现原理
3、实现一个延时订单的应用
1、示例:PutOrder.java
备注:
代码示例地址:chapter-concurrent-plugins