参考博文以及源码
LockSupport主要提供了park, unpark以及park的一些兄弟:parkNano, parkUniti等,当然这些兄弟和park的功能都类似,就是在锁的时间上做了一些限制。
LockSupport简介
用来创建锁和其他同步类的基本线程阻塞原语
核心函数
LockSupport.park(boolean isAbsolute, long time): 线程阻塞. time为等待时间,超过时间自动释放锁
LockSupport.unpark: // 不安全,要确保线程依旧存活
调用的都是unsafe的park, unpark函数。
源码
private LockSupport() {} // Cannot be instantiated.
// 阻塞
public static void park(Object blocker) {
Thread t = Thread.currentThread();
setBlocker(t, blocker); // 将线程阻塞
UNSAFE.park(false, 0L); // 调用park后,无法走下一步(setBlocker(t,null), 直到获得unpark)
setBlocker(t, null); // 通过unpark之后才能走到这一步
}
// 唤醒必须传入具体哪个线程
public static void unpark(Thread thread) {
if (thread != null)
UNSAFE.unpark(thread);
}
// 调用方法:Locklock.park()
block, wait区别:block是因为线程等待获取监视器monitor锁以期进入同步代码块/Object.wait, 通过notify可以被唤醒。
其他问题
Thread.sleep() 和 LockSupport.park()的区别
都是阻塞且不会释放锁资源。但是:
- Thread.sleep()无法从外部唤醒,只能自己醒过来; LockSupport.park()可以被另一个线程调用LockSupport.unpark()
- Thread.sleep()本身是一个native方法,LockSupport.park()底层是调用unsafe的native方法
- sleep抛出了中断异常,park的没有
object.wait()和LockSupport.park()区别
- Object.wait()方法需要在synchronized中执行,LockSupport.park()在任意地方
- wait抛出了中断异常,park的没有
- wait没有超时,只能notify唤醒。park也没有超时,通过unpark唤醒。
- wait前notify跑出异常,park前unpark不会
- wait释放了锁资源,允许其他进程获取锁。但是park没有释放锁资源,知识负责阻塞当前进程。
Object的wait: wait()方法必须在当前获取的锁对象上调用。wait()方法调用时,会释放线程获得的锁,wait()方法返回后,线程又会重新试图获得锁,才能继续往后执行。