摘要:本文学习了ThreadLocal的用法和原理。
环境
Windows 10 企业版 LTSC 21H2
Java 1.8
1 简介
LockSupport是用来创建锁和其他同步类的基本线程阻塞原语,在内部使用凭证的概念来实现阻塞和唤醒,每个线程都有一个凭证,只有1和0两个值,默认是0。
LockSupport中提供了两个方法:
- park()方法会在凭证可用时执行,将凭证从1变成0,用于阻塞线程。
- unpark()方法会在凭证不可用时执行,将凭证从0变成1,用于唤醒线程。
LockSupport中的方法调用的是Unsafe类中的native代码。
2 比较
比较三种阻塞唤醒线程的方式:
- 使用Object的wait()方法和notify()方法:
- 使用wait()方法阻塞线程,使用notify()方法唤醒线程。
- 必须在synchronized代码块内部执行,否则抛出IllegalMonitorStateException。
- 必须先执行wait()方法再执行notify()方法,否则线程会一直等待无法被唤醒。
- 使用Condition的await()方法和signal()方法:
- 使用await()方法阻塞线程,使用signal()方法唤醒线程。
- 必须和Lock组队使用,否则抛出IllegalMonitorStateException。
- 必须先执行await()方法再执行signal()方法,否则线程会一直等待无法被唤醒。
- 使用LockSupport的park()方法和uppark()方法:
- 使用park()方法阻塞线程,使用uppark()方法唤醒线程。
- 不需要在任何代码块内执行,可以在任何地方执行。
- 使用顺序无要求,即使先执行uppark()方法再执行park()方法,也能唤醒线程。
3 使用
示例:
1 | public static void main(String[] args) { |
结果:
1 | b进入 |
4 总结
LockSuport是一个线程阻塞工具类,底层调用的Unsafe中的native代码,所有的方法都是静态方法,可以让线程在任意位置阻塞和唤醒。
两个方法:
- 调用park()方法,将凭证从1变成0,立即返回并继续执行。如果凭证为0则会阻塞,直到unpark()方法将凭证从0变为1。
- 调用unpark()方法,将凭证从0变成1,立即返回并继续执行,多次调用unpark()方法不会累加凭证。如果凭证为1则会阻塞,直到park()方法将凭证从1变为0。
条