文章目录
- 一、创建线程的几种方式?
- 二、线程的同步
- 1.锁
- 2.volatile关键字
- 3.CAS (Compare-And-Swap)
- 4.ConcurrentHashMap 锁分段机制
- 三、线程的协作
- 1.Object的wait()、notify()
- 2.Condition的await()、signal()
- 3.LockSupport
- 4.CountDownLatch 、Semaphore、CyclicBarrier 、BlockingQueue
- 四、线程的中断机制
- 五、异步回调CompletableFuture
- 六、分支合并(ForkJoin)?
提示:线程分为两类:一种是守护线程,一种是用户线程。若JVM中都是守护线程,当前JVM将退出。
一、创建线程的几种方式?
- 创建线程的几种方式
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口
- 线程池
二、线程的同步
1.锁
- 同步代码块
- 同步方法:静态方法的锁是Class类型的对象,非静态方法锁的锁是this。
- Lock锁:可重入锁、公平和非公平锁
- ReadWriteLock 读写锁
2.volatile关键字
作用是: 1.保证可见性 2.禁止指令重排 3.不保证原子性
3.CAS (Compare-And-Swap)
- 基于硬件级别的指令实现的同步原语
- CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。
- Unsafe类提供了CAS操作的native方法
- getAndAddInt正是乐观锁,用CAS代替锁,如果出现竞争,则用自旋的方式继续CAS,直到成功
- 问题:自旋效率问题,ABA问题(从A改成B,然后又改回A)
4.ConcurrentHashMap 锁分段机制
内部采用“锁分段” 机制替代 Hashtable 的独占锁。进而提高性能。
三、线程的协作
1.Object的wait()、notify()
2.Condition的await()、signal()
3.LockSupport
LockSupport是一个线程阻塞工具类,所有的方法都是静态方法,可以让线程在任意位置阻塞
park和unpark其实实现了wait和notify的功能,不过还是有一些差别的:
- park不需要获取某个对象的锁
- park和unpark可以实现类似wait和notify的功能,但是并不和wait和notify交叉,也就是说unpark不会对wait起作用,notify也不会对park起作用。
- park和unpark的使用不会出现死锁的情况
- blocker的作用是在dump线程的时候看到阻塞对象的信息
4.CountDownLatch 、Semaphore、CyclicBarrier 、BlockingQueue
CountDownLatch: 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。
CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
Semaphore是一个有效的流量控制工具,基于AQS共享锁实现。常用它来控制对有限资源的访问。
BlockingQueue阻塞队列
四、线程的中断机制
- 一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。所以,Thread.stop、Thread.suspend、Thread.resume都已经被废弃了。
- Java提供了一种用于停止线程的机制——中断 中断只是一种协作机制,Java没有给中断增加任何语法,中断的过程完全需要程序员自己实现。
五、异步回调CompletableFuture
CompletableFuture相当于一个Task编排工具。CompletableFuture可以指定异步处理流程:
- thenAccept()处理正常结果;
- exceptional()处理异常结果;
- thenApplyAsync()用于串行化另一个CompletableFuture
- anyOf()和allOf()用于并行化多个CompletableFuture
六、分支合并(ForkJoin)?