文章目录
一、 LockSupport
- LockSupport 位于rt.jar 包里面,本身是个工具类,主要作用是挂起和唤醒线程。该工具类是创建锁和其他同步类的基础。
LockSupport 类与每一个使用它的线程都会关联一个许可证,在默认情况下调用LockSupport 类的方法的线程是不持有许可证的。LockSupport 是使用Unsafe类实现的。
1、void park()
如果调用 park 方法的线程已经拿到了与LockSupport 关联的许可证,则调用 LockSupport.park()时会马上返回,否则调用线程会被禁止参与线程的调度,也就是会被阻塞挂起。
其他线程调用unpark(Thread thread) 方法并且将当前线程作为参数时,调用park方法而被阻塞的线程会返回。另外,如果其他线程调用了阻塞线程的 interrupt 方法,设置了中断标志或者线程被虚假唤醒,则阻塞线程也会返回。所以在调用park方法时最好也使用循环条件判断方式。
需要注意的是,因调用park 方法而被阻塞的线程被其他线程中断而返回时并不会抛出 Interrupt的Exception 异常。
2、void unpark(Thread thread)
当一个线程调用unpark时,如果参数thread线程没有持有thread 与 LockSupport 类关联的许可证,则让thread 持有。
如果thread 之前因为调用park 被挂起,则调用unpark 后,该线程会被唤醒。
如果thread之前没有调用park,则调用unpark 方法后,在调用park方法,其会立即返回。
public static void main(String[] args) throws InterruptedException {
Runnable r1 = () -> {
System.out.println("r1 begin");
LockSupport.park();
System.out.println("r1 end");
};
Thread thread = new Thread(r1);
thread.start();
Thread.sleep(1000);
System.out.println("main thread begin unpark");
LockSupport.unpark(thread);
}
3、void parkNanos(long nanos)
和park()方法类似,如果调用park()方法的线程已经拿到了与LockSupport关联的许可证,则调用LockSupport.parkNano(long nanos)方法后会马上返回。该方法的不同在于,如果没有拿到许可证,则调用线程会被挂起nanos时间后修改为自动返回。
此外,park()方法还支持带有blocker参数的方法void park(Object blocker)方法,当线程在没有持有许可证的情况下调用park()方法而被挂起时,这个blocker的对象会被记录到线程内部。
4、void park(Object blocker)
Thread 类里有个变量volatile Object parkBlocker,用来存放park方法传递的blocker对象,也就是blocker 变量存放到了调用park方法的线程的成员变量里面。