多线程同步工具——LockSupport

用例1:子线程等待主线程发放许可!

public static void main(String[] args) {
    Thread thread = new Thread(){
        public void run(){
            System.out.println("子线程 -> 测试通行许可!");
            LockSupport.park();
            System.out.println("子线程 -> 已通行!");
        }
    };
    thread.start();

    System.out.println("主线程 -> 休眠1秒!");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("主线程 -> 发放通行许可于子线程!");
    LockSupport.unpark(thread);
    
    /*
        运行结果:
        主线程 -> 休眠1秒!
        子线程 -> 测试通行许可!
        主线程 -> 发放通行许可于子线程!
        子线程 -> 已通行!
     */
}

用例2:主线程提前发放许可给子线程!

public static void main(String[] args) {
    Thread thread = new Thread(){
        public void run(){
            System.out.println("子线程 -> 休眠1秒!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("子线程 -> 测试通行许可!");
            LockSupport.park();
            System.out.println("子线程 -> 已通行!");
        }
    };
    thread.start();
    
    System.out.println("主线程 -> 提前发放通行许可于子线程!");
    LockSupport.unpark(thread);
    
    /*
        运行结果:
        主线程 -> 提前发放通行许可于子线程!
        子线程 -> 休眠1秒!
        子线程 -> 测试通行许可!
        子线程 -> 已通行!
     */
}

用例3:子线程传递数据给主线程。

public static void main(String[] args) {
    Thread thread = new Thread(){
        public void run(){
            System.out.println("子线程 -> 测试通行许可!并提供通行证:A");
            LockSupport.park(new String("A"));
            System.out.println("子线程 -> 已通行!");
        }
    };
    thread.start();

    System.out.println("主线程 -> 休眠1秒!");
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("主线程 -> 检查并处理子线程的通行证:" + LockSupport.getBlocker(thread));
    System.out.println("主线程 -> 许可子线程通行!");
    LockSupport.unpark(thread);
    
    /*
        运行结果:
        主线程 -> 休眠1秒!
        子线程 -> 测试通行许可!并提供通行证:A
        主线程 -> 检查并处理子线程的通行证:A
        主线程 -> 许可子线程通行!
        子线程 -> 已通行!
     */
}

全部操作:

  • park()/park(Object)
    等待通行准许。
  • parkNanos(long)/parkNanos(Object, long)
    在指定运行时间(即相对时间)内,等待通行准许。
  • parkUntil(long)/parkUntil(Object, long)
    在指定到期时间(即绝对时间)内,等待通行准许。
  • unpark(Thread)
    发放通行准许或提前发放。(注:不管提前发放多少次,只用于一次性使用。)
  • getBlocker(Thread)
    进入等待通行准许时,所提供的对象。

主要用途:

  当前线程需要唤醒另一个线程,但是只确定它会进入阻塞,但不确定它是否已经进入阻塞,因此不管是否已经进入阻塞,还是准备进入阻塞,都将发放一个通行准许。

正确用法:

  把LockSupport视为一个sleep()来用,只是sleep()是定时唤醒,LockSupport既可以定时唤醒,也可以由其它线程唤醒。

原文地址:https://www.cnblogs.com/hvicen/p/6217303.html