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; } }