1、使用LockSupport的part/unpark实现
package com.ares.thread; import java.util.concurrent.locks.LockSupport; public class WaitAndNotifyDemo { public static void main(String[] args) { MThread myThread = new MThread(Thread.currentThread()); myThread.start(); System.out.println("before park"); // 获取许可 表示当前线程将会等待,直至获得许可 LockSupport.park("ParkAndUnparkDemo"); System.out.println("after park"); } } class MThread extends Thread { private Object object; public MThread(Object object) { this.object = object; } public void run() { System.out.println("before unpark"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 获取blocker System.out.println("Blocker info " + LockSupport.getBlocker((Thread) object)); // 释放许可 必须把等待获得许可的线程作为参数进行传递,好让此线程继续运行 LockSupport.unpark((Thread) object); // 休眠500ms,保证先执行park中的setBlocker(t, null); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } // 再次获取blocker System.out.println("Blocker info " + LockSupport.getBlocker((Thread) object)); System.out.println("after unpark"); } }
运行结果:
before park
before unpark
Blocker info ParkAndUnparkDemo
after park
Blocker info null
after unpark
说明:本程序先执行park,然后在执行unpark,进行同步,并且在unpark的前后都调用了getBlocker,可以看到两次的结果不一样,并且第二次调用的结果为null,这是因为在调用unpark之后,执行了Lock.park(Object blocker)函数中的setBlocker(t, null)函数,所以第二次调用getBlocker时为null。
同时,先调用unpark,再调用park时,仍能够正确实现同步,不会造成由wait/notify调用顺序不当所引起的阻塞。因此park/unpark相比wait/notify更加的灵活。