多线程同步工具——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既可以定时唤醒,也可以由其它线程唤醒。