LockSupport并发等待基本模型。写的个测试,具体请看注释。java
package test; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; /** * @author Wei.Chou(weichou2010@gmail.com) * @version 1.0, 12/08/2016 */ public class ParkTest { private static volatile boolean resulted; private static volatile boolean completed; private static volatile boolean end0; private static volatile boolean end1; private static final AtomicInteger parkCount = new AtomicInteger(0); private static final Set<Thread> set = new CopyOnWriteArraySet<>(); private static volatile Object result; public static void main(String[] args) { new Thread() { @Override public void run() { int i = 0; while (true) { while (end0) Thread.yield(); System.out.println("thread started"); sync(); end0 = true; System.out.println("thread end +++"); while (!end1) Thread.yield(); resulted = false; completed = false; System.out.println(">>>>>>>>>>>>>>>>>>>> thread +++ loop:" + i++ + ", parkCount:" + parkCount.get()); end1 = false; } } }.start(); new Thread() { @Override public void run() { int i = 0; while (true) { while (end1) Thread.yield(); System.out.println("thread1 started"); work(); end1 = true; System.out.println("thread1 end ---"); while (!end0) Thread.yield(); System.out.println("<<<<<<<<<<<<<<<<<<<< thread1 --- loop:" + i++ + ", parkCount:" + parkCount.get()); set.clear(); end0 = false; } } }.start(); } private static Object sync() { try { Thread.sleep((int) (Math.random() * 100)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("thread sync calling"); final Thread t = Thread.currentThread(); set.add(t); if (Math.random() < .5) { Thread.yield(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } boolean unparked = false; while (true) { System.out.println("thread loop ~~~~~~~~~~~~~~~~~~~~~~~~~~~-parkCount:" + parkCount.get()); if (completed) { if (set.contains(t)) { set.remove(t); } else { System.out.println("thread park ###########################-parkCount:" + parkCount.incrementAndGet()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // parkCount.incrementAndGet(); // 消化掉那个unpark if (!unparked) LockSupport.park(); } return result; } else if (resulted) { // 走这个case是由于颇有可能在上面set.add(t)以前, 这个状态就已经设置了。 // 那么unpark()是在add(t)以前仍是以后, 状况是随机的, 无从知晓。 // 但又不能总yield(), 若是状态没有设置, 不知道要等多久, 那么LockSupport.park()是最合适的。 //**********// // 此时是个量子态,一切都不稳定,那就再来一遍。 // 可是这个状态的持续时间极短暂,所以yield()是理想方法。 Thread.yield(); } else { System.out.println("thread park ???????????????????????????-parkCount:" + parkCount.incrementAndGet()); // parkCount.incrementAndGet(); // 没有获得结果,那就等着。 LockSupport.park(); // 保险起见, 再来一遍看看, 而不直接返回。 unparked = true; } } } private static void work() { try { System.out.println("thread1 working"); // work time Thread.sleep((int) (Math.random() * 3000)); } catch (InterruptedException e) { e.printStackTrace(); } // 这里只修改结果,完成的标识放最后 result = new Object(); System.out.println("thread1 resulted"); resulted = true; for (Thread t : set) { System.out.println("thread1 unpark---------------------------parkCount:" + parkCount.decrementAndGet()); // parkCount.decrementAndGet(); LockSupport.unpark(t); set.remove(t); } System.out.println("thread1 completed"); completed = true; } }