LockSupport详解
LockSupport详解
简介
- LockSupport用来创建锁或其他同步类的基本线程阻塞原语.
- 调用
park()方法时,当前线程将等待,直到获取许可. - 调用
unpark()方法时,必须将等待获得许可的线程作为参数,使得等待的线程继续进行.
核心方法
Unsafe类的park和unpark
LockSupport的park()和unpark()是调用Unsafe类的park()和unpark()实现的.
park():阻塞线程.unpark():释放线程,激活调用park()后阻塞的线程.
park()方法
// 调用park后线程会被阻塞,三种情况下线程获得许可:
// 1. 其他线程调用此线程的unpark()
// 2. 其他线程中断此线程
// 3. 该调用无理由返回
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker); // 设置当前线程的blocker
UNSAFE.park(false, 0L); // 阻塞当前线程
setBlocker(t, null); // 设置当前线程的blocker为null
}
注:(调用两次设置blocker的原因)
首次设置好blocker后,调用park()阻塞线程,等待其他线程调用unpark()来激活线程.
当前线程再次被激活后,再次设置blocker为null.否则,在获取blocker时,得到的是上一次设置的blocker.
parkNanos
在许可可用前阻塞当前线程,最多等待指定的等待时间.
parkUntil
在指定时限前禁止当前线程,除非许可可用.
unpark
- 若给定线程的许可不可用,则使其可用,解除阻塞状态.
- 若线程未启动,则无效果.
使用park/unpark实现线程同步
示例:
// 一个park阻塞的线程,被其他线程unpark()后继续执行
threadA t1 = new threadA();
t1.start();
LockSupport.unpark(t1);
// t1.interrupt(); // 中断park的线程也可将其唤醒
// --------------------
class threadA{
Thread.sleep(1000); // 先unpark,再park一样可行
LockSupport.park();
System.out.println(Thread.currentThread().getName());
}
// 先对一个线程unpark(),然后其调用park()后,线程继续执行
threadA t1 = new threadA();
t1.start();
LockSupport.unpark(t1);
// t1.interrupt(); // 中断park的线程也可将其唤醒
// --------------------
class threadA{
LockSupport.park();
System.out.println(Thread.currentThread().getName());
}
小结
Thread.sleep()与Object.wait()的区别
Thread.sleep() |
Object.wait() |
|
|---|---|---|
| 锁 | 不会释放占有的锁 | 会释放占有的锁 |
| 参数 | 必须传入睡眠的时间 | 可以传时间,也可不传 |
| 时间 | 时间到了会自动唤醒,继续执行 | 没有时间,需要等待notify唤醒;有时间,则被唤醒或时间到了自动唤醒 |
Thread.sleep()与Condition.await()的区别
基本相同,Condition.await()是调用LockSupport.part()阻塞当前线程.
流程:
- 将当前线程加入条件队列.
- 释放锁.
- 调用
LockSupport.park()阻塞当前线程.
Thread.sleep()和LockSupport.park()的区别
Thread.sleep() |
LockSupport.park() |
|
|---|---|---|
| 功能 | 阻塞当前线程,不释放占有的锁 | 阻塞当前线程,不释放占有的锁 |
| 唤醒 | 只能自己唤醒自己 | 可以被其他线程通过unpark()唤醒 |
| 异常 | 声明抛出异常 | 不需要捕获异常 |
Object.wait()和LockSupport.park()的区别
Object.wait() |
LockSupport.park() |
|
|---|---|---|
| 使用 | 只能在synchronized块执行 | 在任意地方执行 |
| 异常 | 声明抛出中断异常 | 不需要捕获异常 |
| 超时 | 不带超时,需要其他线程执行notify()唤醒 |
不带超时,需要其他线程执行unpark()唤醒 |
| 睡眠前唤醒 | 抛出异常 | 不会被阻塞,跳过park(),继续执行 |
参考:
本文来自博客园,作者:战五渣渣渣渣渣,转载请注明原文链接:https://www.cnblogs.com/truestoriesavici01/p/13224742.html

浙公网安备 33010602011771号