1 Realize with wait and notify
public class NotifyFreeLock { volatile List lists = new ArrayList<>(); public void add(Object o) { lists.add(0); } public int size() { return lists.size(); } public static void main(String[] args) { NotifyHoldingLock c = new NotifyHoldingLock(); final Object lock = new Object(); new Thread(() -> { synchronized (lock) { System.out.println("t2启动"); if (c.size() != 5) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("The end of t2"); //Notify t1 to continue execution lock.notify(); } }, "t2").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { System.out.println("t1 start"); synchronized (lock) { for (int i = 0; i <10; i++) { c.add(new Object()); System.out.println("add " + i); if (c.size() == 5) { lock.notify(); //Release the lock and let t2 be executed try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }, "t1").start(); } }
2 Implemented with LockSupport
public class T_LockSupport2 { volatile List lists = new ArrayList<>(); public void add(Object o) { lists.add(o); } public int size() { return lists.size(); } static Thread t1 =null,t2 = null; public static void main(String[] args) { T_LockSupport2 c = new T_LockSupport2(); t1 = new Thread(() -> { System.out.println("t1启动"); for (int i = 0; i < 10; i++) { c.add(new Object()); System.out.println("add " + i); if (c.size() == 5) { LockSupport.unpark(t2); LockSupport.park(); } } System.out.println("t2 结束"); }, "t2"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } t2 = new Thread(() -> { LockSupport.park(); System.out.println("t2 结束"); LockSupport.unpark(t1); }, "t2"); t2.start(); t1.start(); } }
3 Realize with Semaphore
public class T_Semaphore { // 添加volatile,使t2能够得到通知 volatile List lists = new ArrayList(); public void add(Object o) { lists.add(o); } public int size() { return lists.size(); } static Thread t1 = null, t2 = null; public static void main(String[] args) { T_Semaphore c = new T_Semaphore(); Semaphore s = new Semaphore(1); t1 = new Thread(() -> { try { s.acquire(); for (int i = 0; i < 5; i++) { c.add(new Object()); System.out.println("add " + i); } s.release(); } catch (InterruptedException e) { e.printStackTrace(); } t2.start(); try { t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } try { s.acquire(); for (int i =5;i<10;i++){ System.out.println(i); } s.release(); } catch (InterruptedException e) { e.printStackTrace(); } },"t1"); t2 = new Thread(()->{ try { s.acquire(); System.out.println("t2 结束"); s.release(); } catch (InterruptedException e) { e.printStackTrace(); } },"t2"); t1.start(); } }
4 Implemented with two CountDownLatch
public class T_CountDownLatch { volatile List lists = new ArrayList<>(); public void add(Object o) { lists.add(o); } public int size() { return lists.size(); } public static void main(String[] args) { T_CountDownLatch c = new T_CountDownLatch(); CountDownLatch latch = new CountDownLatch(1); CountDownLatch latch2 = new CountDownLatch(1); new Thread(() -> { System.out.println("t2启动"); if (c.size() != 5) { try { latch.await(); latch2.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("t2 结束"); }, "t2").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->{ System.out.println("t1启动"); for (int i = 0; i <10 ; i++) { c.add(new Object()); System.out.println("add "+i); if(c.size() == 5 ){ latch.countDown(); try { latch2.await(); } catch (InterruptedException e) { e.printStackTrace(); } } } },"t1").start(); } }