`
Jen
  • 浏览: 56762 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JUC代码浅析[5]——基于AQS的CountDownLatch

    博客分类:
  • java
阅读更多

JUC代码浅析[5]——基于AQSCountDownLatch

       CountDownLatch是一种使线程等待一组其他线程操作完成再开始的同步方式,初始化时设置一个计数值,每完成一次操作后countDown()对计数值减操作,线程等待await()直到计数值为0

       为了说明使用场景拷贝了代码注释中的例子,

class Driver { // ...

   void main() throws InterruptedException {

     CountDownLatch startSignal = new CountDownLatch(1);

     CountDownLatch doneSignal = new CountDownLatch(N);

 

     for (int i = 0; i < N; ++i) // create and start threads

       new Thread(new Worker(startSignal, doneSignal)).start();

 

     doSomethingElse();           

     startSignal.countDown();      // 所有的worker线程开始

     doSomethingElse();

     doneSignal.await();           // 等待doneSignal计数值为0

   }

 }

 

 class Worker implements Runnable {

   private final CountDownLatch startSignal;

   private final CountDownLatch doneSignal;

   Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {

      this.startSignal = startSignal;

      this.doneSignal = doneSignal;

   }

   public void run() {

      try {

        startSignal.await();//等待主线程把startSignal计数值减到0countDown

        doWork();

        doneSignal.countDown();//doneSignal的计数值剪1

      } catch (InterruptedException ex) {} // return;

   }

 

   void doWork() { ... }

 }

 

       在理解AQS的基础上,分析CountDownLatch是比较简单的,它是基于共享模式的实现。下面是await()方法的实现

    public void await() throws InterruptedException {

        sync.acquireSharedInterruptibly(1);

    }

 

最终会调用synctryAcquireShared方法判断是否可以获得锁,下面的代码说明了state等于0时就可以获得锁,await也就将执行结束,线程就可以往下继续执行了

        public int tryAcquireShared(int acquires) {

            return getState() == 0? 1 : -1;

        }

 

再看countDown方法,

    public void countDown() {

        sync.releaseShared(1);

    }

 

最终会通过synctryReleaseShared来尝试释放锁,就是通过CAS操作来减少计数

        public boolean tryReleaseShared(int releases) {

            // Decrement count; signal when transition to zero

            for (;;) {

                int c = getState();

                if (c == 0)

                    return false;

                int nextc = c-1;

                if (compareAndSetState(c, nextc))

                    return nextc == 0;

            }

        }

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics