模仿CountDownLatch类自定义倒时计时器
简介
这里模仿CountDownLatch类自定义到时计时器,利用AQS模板中的尝试获得共享和释放共享
1、MyCountDownLatch
package com.jacky; import com.sun.corba.se.impl.orbutil.concurrent.Sync; import java.util.concurrent.locks.AbstractQueuedSynchronizer; /** * Created by jacky on 2018/2/11. */ public class MyCountDownLatch { private final Sync sync; public MyCountDownLatch(int count){ sync = new Sync(count); } static class Sync extends AbstractQueuedSynchronizer{ public Sync(int count){ setState(count); } /** * 计时器小于0的时候就会继续等待 * @param arg * @return */ @Override protected int tryAcquireShared(int arg) { return getState() ==0 ?1 : -1; } @Override protected boolean tryReleaseShared(int arg) { for (;;){ int state = getState(); System.out.println("-------"+state+"---------"); if (state == 0){ return false; } int newState = state-1; if (compareAndSetState(state,newState)){ return newState==0; } } } } /** *state不为0就把线程挂起 * @throws InterruptedException */ public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); } /** * 倒时计时器减1 */ public void countDown(){ sync.releaseShared(1); } }
2、测试
package com.jacky; import java.util.concurrent.CountDownLatch; /** * Created by jacky on 2018/2/11. */ public class CountDownLatchDemo { public static void main(String[] args) { Thread mainThread = Thread.currentThread(); //CountDownLatch latch = new CountDownLatch(4); MyCountDownLatch latch = new MyCountDownLatch(4); Runnable runnable = new Runnable() { @Override public void run() { try { Thread.sleep((int)(Math.random()*100)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("currentThread--"+Thread.currentThread().getName()+"--mainThread--"+mainThread.getName() +"--mainThreadStatus--"+mainThread.getState()); latch.countDown(); } }; Thread thread1 = new Thread(runnable); Thread thread2 = new Thread(runnable); Thread thread3 = new Thread(runnable); Thread thread4 = new Thread(runnable); thread1.start(); thread2.start(); thread3.start(); thread4.start(); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("mainThread end"); } }