1、volatile,最轻量的同步机制
volatile 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某
个变量的值,这新值对其他线程来说是立即可见的。
参见代码:
![](https://img.haomeiwen.com/i26777047/9a530e66ee7f09ff.png)
不加 volatile 时,子线程无法感知主线程修改了 ready 的值,从而不会退出循环,
而加了 volatile 后,子线程可以感知主线程修改了 ready 的值,迅速退出循环。
但是 volatile 不能保证数据在多个线程下同时写时的线程安全,
volatile 最适用的场景:一个线程写,多个线程读。
2、ThreadLocal 和 Synchonized的比较
ThreadLocal 和 Synchonized 都用于解决多线程并发訪问。可是 ThreadLocal
与 synchronized 有本质的差别。synchronized 是利用锁的机制,使变量或代码块
在某一时该仅仅能被一个线程訪问。而 ThreadLocal 为每个线程都提供了变量的
副本,使得每个线程在某一时间訪问到的并非同一个对象,这样就隔离了多个线
程对数据的数据共享。
3、ThreadLocal 的使用
ThreadLocal 类接口很简单,只有 4 个方法,我们先来了解一下:
• void set(Object value)
设置当前线程的线程局部变量的值。
• public Object get()
该方法返回当前线程所对应的线程局部变量。
• public void remove()
将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是 JDK
5.0 新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动
被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它
可以加快内存回收的速度。
• protected Object initialValue()
返回该线程局部变量的初始值,该方法是一个 protected 的方法,显然是为
了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第 1 次调用 get()
或 set(Object)时才执行,并且仅执行 1 次。ThreadLocal 中的缺省实现直接返回一
个 null。
public final static ThreadLocal<String> RESOURCE = new
ThreadLocal<String>();RESOURCE代表一个能够存放String类型的ThreadLocal对象。
此时不论什么一个线程能够并发访问这个变量,对它进行写入、读取操作,都是
线程安全的。
4、引发的内存泄漏分析
根据我们前面对 ThreadLocal 的分析,我们可以知道每个 Thread 维护一个
ThreadLocalMap,这个映射表的 key 是 ThreadLocal 实例本身,value 是真正需
要存储的 Object,也就是说 ThreadLocal 本身并不存储值,它只是作为一个 key
来让线程从 ThreadLocalMap 获取 value。仔细观察 ThreadLocalMap,这个 map
是使用 ThreadLocal 的弱引用作为 Key 的,弱引用的对象在 GC 时会被回收。
因此使用了 ThreadLocal 后,
引用链如图所示:
![](https://img.haomeiwen.com/i26777047/11aaf15684f48f45.png)
图中的虚线表示弱引用。
这样,当把 threadlocal 变量置为 null 以后,没有任何强引用指向 threadlocal
实例,所以 threadlocal 将会被 gc 回收。这样一来,ThreadLocalMap 中就会出现
key 为 null 的 Entry,就没有办法访问这些 key 为 null 的 Entry 的 value,如果当前
线程再迟迟不结束的话,这些 key 为 null 的 Entry 的 value 就会一直存在一条强
引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value,而这块 value 永
远不会被访问到了,所以存在着内存泄露。
只有当前 thread 结束以后,current thread 就不会存在栈中,强引用断开,
Current Thread、Map value 将全部被 GC 回收。最好的做法是不在需要使用
ThreadLocal 变量后,都调用它的 remove()方法,清除数据
5、等待/通知机制
是指一个线程 A 调用了对象 O 的 wait()方法进入等待状态,而另一个线程 B
调用了对象 O 的 notify()或者 notifyAll()方法,线程 A 收到通知后从对象 O 的 wait()
方法返回,进而执行后续操作。上述两个线程通过对象 O 来完成交互,而对象
上的 wait()和 notify/notifyAll()的关系就如同开关信号一样,用来完成等待方和通
知方之间的交互工作。
notify():
通知一个在对象上等待的线程,使其从 wait 方法返回,而返回的前提是该线程
获取到了对象的锁,没有获得锁的线程重新进入 WAITING 状态。
notifyAll():
通知所有等待在该对象上的线程
wait()
调用该方法的线程进入 WAITING 状态,只有等待另外线程的通知或被中断
才会返回.需要注意,调用 wait()方法后,会释放对象的锁
wait(long)
超时等待一段时间,这里的参数时间是毫秒,也就是等待长达n 毫秒,如果没有
通知就超时返回
wait (long,int)
对于超时时间更细粒度的控制,可以达到纳秒
6、等待和通知的标准范式
![](https://img.haomeiwen.com/i26777047/4ac37a266e707de2.png)
![](https://img.haomeiwen.com/i26777047/dc12722dd1f932a9.png)
在调用 wait()、notify()系列方法之前,线程必须要获得该对象的对象级 别锁,即只能在同步方法或同步块中调用 wait()方法、notify()系列方法,
进入 wait()方法后,当前线程释放锁,在从 wait()返回前,线程与其他线程竞争重新获得锁,执行 notify()系列方法的线程退出调用了 notifyAll 的 synchronized代码块的时候后,他们就会去竞争。如果其中一个线程获得了该对象锁,它就会继续往下执行,在它退出 synchronized 代码块,释放锁后,其他的已经被唤醒的线程将会继续竞争获取该锁,一直进行下去,直到所有被唤醒的线程都执行完毕。
7、notify 和 notifyAll 应该用谁
尽可能用 notifyall(),谨慎使用 notify(),因为 notify()只会唤醒一个线程,我
们无法确保被唤醒的这个线程一定就是我们需要唤醒的线程。
8、调用 yield() 、sleep()、wait()、notify()等方法对锁有何影响?
- yield() 、sleep()被调用后,都不会释放当前线程所持有的锁。
- 调用 wait()方法后,会释放当前线程持有的锁,而且当前被唤醒后,会重新
去竞争锁,锁竞争到后才会执行 wait 方法后面的代码。 - 调用 notify()系列方法后,对锁无影响,线程只有在 syn 同步代码执行完后才
会自然而然的释放锁,所以 notify()系列方法一般都是 syn 同步代码的最后一行。
9、Fork-Join 原理
![](https://img.haomeiwen.com/i26777047/933e3285b329a3bb.png)
10、工作密取
- 即当前线程的 Task 已经全被执行完毕,则自动取到其他线程的 Task 池中取
出 Task 继续执行。- ForkJoinPool 中维护着多个线程(一般为 CPU 核数)在不断地执行 Task,每
个线程除了执行自己职务内的 Task 之外,还会根据自己工作线程的闲置情况去
获取其他繁忙的工作线程的 Task,如此一来就能能够减少线程阻塞或是闲置的时
间,提高 CPU 利用率。
11、CountDownLatch
闭锁,CountDownLatch 这个类能够使一个线程等待其他线程完成各自的工
作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动
所有的框架服务之后再执行。
CountDownLatch 是通过一个计数器来实现的,计数器的初始值为初始任务
的数量。每当完成了一个任务后,计数器的值就会减 1
(CountDownLatch.countDown()方法)。当计数器值到达 0 时,它表示所有的已
经完成了任务,然后在闭锁上等待 CountDownLatch.await()方法的线程就可以恢
复执行任务。
![](https://img.haomeiwen.com/i26777047/1b5a173d2340294f.png)
12、Callable、Future和FutureTask
![](https://img.haomeiwen.com/i26777047/ac7b8e7b9037de9d.png)
13、Exchange的作用、应用场景和实战
![](https://img.haomeiwen.com/i26777047/602cb41d2b9b88dc.png)
14、Semaphore的作用、应用场景和实战
![](https://img.haomeiwen.com/i26777047/75ea9a58686b8b97.png)
网友评论