Java并发编程之java.util.concurrent包——CountDownLatch篇

概念

  • countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
  • 是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。

源码

  • countDownLatch类中只提供了一个构造器:
//参数count为计数值
public CountDownLatch(int count) {
    
      };  
  • 类中有三个方法是最重要的:
//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException {
    
     };   
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
    
     };  
//将count值减1
public void countDown() {
    
     };  

下面我们就自己来自定义实现一个CountDownLatch

代码如下:

public class KaneCountDownLatch {
    
    
    private KaneCountDownLatch.Sync sync;

    public KaneCountDownLatch(int count) {
    
    
        this.sync = new KaneCountDownLatch.Sync(count);
    }

    public void countDown() {
    
    
        this.sync.releaseShared(1);
    }

    public void await() {
    
    
        this.sync.acquireShared(1);
    }

    class Sync extends AbstractQueuedSynchronizer {
    
    
        public Sync(int count) {
    
    
            this.setState(count);
        }

        protected int tryAcquireShared(int arg) {
    
    
            return this.getState() == 0 ? 1 : -1;
        }

        protected boolean tryReleaseShared(int arg) {
    
    
            int c;
            int nextc;
            do {
    
    
                c = this.getState();
                if (c == 0) {
    
    
                    return false;
                }

                nextc = c - 1;
            } while(!this.compareAndSetState(c, nextc));

            return nextc == 0;
        }
    }
}

测试代码如下:

public class CountDownLatch_Demo {
    
    

    public static void main(String[] args) throws InterruptedException {
    
    
        KaneCountDownLatch latch = new KaneCountDownLatch(6); //计数为6


        for (int i = 0; i <6 ; i++) {
    
    
            new Thread(()->{
    
    
                System.out.println("开始准备.....");
                latch.countDown();//计数减一
            }).start();
            Thread.sleep(1000);
        }

        latch.await(); //每个线程执行一次,则-1,在latch为0的时候开始向下运行 这是这些线程都准备就绪,然后去一起干同一件事

        //还有一种方式, 将一个活分为多段,每个线程去干一段
//        for (int i = 0; i <6 ; i++) {
    
    
//            new Thread(()->{
    
    
//                  latch.countDown(); // 计数减一
//                try {
    
    
//                    latch.await(); // 阻塞 -- > 0
//                    System.out.println("线程:"+Thread.currentThread().getName()+"执行完毕");
//                } catch (InterruptedException e) {
    
    
//                    e.printStackTrace();
//                }
//            }).start();
//        }

        System.out.println("开始干活....");
    }
}

CountDownLatch和CyclicBarrier区别:

  • countDownLatch是一个计数器,线程完成一个记录一个,计数器递减,只能只用一次
  • CyclicBarrier的计数器更像一个阀门,需要所有线程都到达,然后继续执行,计数器递增,提供reset功能,可以多次使用

猜你喜欢

转载自blog.csdn.net/Number_oneEngineer/article/details/119383443