LockSupport 可以用于阻塞当前线程的执行,以及唤醒指定的线程,常用的方法包括park() 和 unpark(thread),能精确控制线程,比 Object 的 wait 和 notify 方法更灵活。
public class LockSupportTest {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
for (int i=0; i<20; i++) {
System.out.println(i);
if (i == 5) {
/** 歇一会儿吧 */
LockSupport.park();
}
if (i == 18) {
/** 歇一会儿吧 */
LockSupport.park();
}
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
try {
/** 主线程sleep 10 秒*/
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
/** 唤醒 thread 线程*/
LockSupport.unpark(thread);
try {
/** 主线程sleep 5 秒*/
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
/** 唤醒 thread 线程*/
LockSupport.unpark(thread);
}
}
输出结果:
0
2021-07-19 12:06:31
1
2021-07-19 12:06:32
2
2021-07-19 12:06:33
3
2021-07-19 12:06:34
4
2021-07-19 12:06:35
5
2021-07-19 12:06:41
6
2021-07-19 12:06:42
7
2021-07-19 12:06:43
8
2021-07-19 12:06:44
9
2021-07-19 12:06:45
10
2021-07-19 12:06:46
11
2021-07-19 12:06:47
12
2021-07-19 12:06:48
13
2021-07-19 12:06:49
14
2021-07-19 12:06:50
15
2021-07-19 12:06:51
16
2021-07-19 12:06:52
17
2021-07-19 12:06:53
18
2021-07-19 12:06:54
19
2021-07-19 12:06:55
解释一下:
park() 方法不需要加锁就可以实现线程的阻塞,unpark() 方法实现线程的唤醒。
unpark()方法如果先于park方法被调用,则不会阻塞线程,例如上面代码在i==18的时候没有阻塞,直接继续打印了,因为在此之前主线程已经调用了 unpark 方法唤醒 thread 线程了。