Java基础-并发编程-LockSupport工具类

Java工程师知识树 / Java基础


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

你可能感兴趣的:(Java基础-并发编程-LockSupport工具类)