Java基础-并发编程-LockSupport工具类
2021-02-14 本文已影响0人
HughJin
LockSupport工具类
不管是ReentrantReadWriteLock还是ReentrantLock,当需要阻塞或唤醒一个线程的时候,都会使用LockSupport工具类完成相应的工作。
LockSupport类,是JUC包中的一个工具类,用于创建锁和其他同步类的基本线程阻塞原语。
实现线程间的协作有三种方式:
- Object类的wait()和notify();
- Condition接口的await()和signal();
- LockSupport类的park()和unpark(Thread)
使用Condition的await()、signal()更加安全和高效;使用LockSupport类的park()和unpark(Thread)更加具体,可以唤醒指定线程。
常用方法 | 方法描述 |
---|---|
void park() | 阻塞当前线程,如果掉用unpark(Thread)方法或被中断,才能从park()返回 |
void parkNanos(long nanos) | 阻塞当前线程,超时返回,阻塞时间最长不超过nanos纳秒 |
void parkUntil(long deadline) | 阻塞当前线程,直到deadline时间点 |
void unpark(Thread) | 唤醒处于阻塞状态的线程 |
LockSupport实现线程协作原理:
LockSupport类使用了一种名为Permit(许可证)的概念来做到阻塞和唤醒线程的功能,可以把许可看成是一种(0,1)信号量(Semaphore),但与Semaphore不同的是,许可的累加上限是1。初始时,permit为0,当调用unpark()方法时,线程的permit加1,当调用park()方法时,如果permit为0,则调用线程进入阻塞状态。
通过源码可以发现,LockSupport的park和unpark方法都是通过sun.misc.Unsafe类的park和unpark方法实现的。
LockSupport方法测试代码:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
public class LockExample4 {
public static void main(String[] args) throws Exception {
Thread t1 = new Thread(() -> {
System.out.println("LockSupport.park.before:" + Thread.currentThread().getName() + ":" + Thread.currentThread().getState());
LockSupport.park();
System.out.println("LockSupport.park.after:" + Thread.currentThread().getName() + ":" + Thread.currentThread().getState());
System.out.println("LockSupport.park.after:" + Thread.currentThread().getName() + ":" + Thread.currentThread().getState());
System.out.println("LockSupport.park.after:" + Thread.currentThread().getName() + ":" + Thread.currentThread().getState());
System.out.println("LockSupport.park.after:" + Thread.currentThread().getName() + ":" + Thread.currentThread().getState());
}, "线程一");
t1.start();
TimeUnit.SECONDS.sleep(2);
new Thread(() -> {
System.out.println("LockSupport.unpark.before:" + t1.getName() + ":" + t1.getState());
LockSupport.unpark(t1);
System.out.println("LockSupport.unpark.after:" + t1.getName() + ":" + t1.getState());
System.out.println("LockSupport.unpark.after:" + t1.getName() + ":" + t1.getState());
System.out.println("LockSupport.unpark.after:" + t1.getName() + ":" + t1.getState());
}, "线程二").start();
}
}
//打印结果
LockSupport.park.before:线程一:RUNNABLE
LockSupport.unpark.before:线程一:WAITING
LockSupport.unpark.after:线程一:WAITING
LockSupport.park.after:线程一:RUNNABLE
LockSupport.park.after:线程一:RUNNABLE
LockSupport.park.after:线程一:RUNNABLE
LockSupport.park.after:线程一:RUNNABLE
LockSupport.unpark.after:线程一:BLOCKED
LockSupport.unpark.after:线程一:TERMINATED