java并发之CountDownLatch和CyclicBarrier的运用

一 CountDownLatch

1.定义

      允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。

2.主要方法

 (1)构造方法

    • CountDownLatch(int count)

      构造一个以给定计数 CountDownLatch CountDownLatch。

 (2)countdown()

    • countDown()
      • 减少锁存器的计数,如果计数达到零,释放所有等待的线程。
      • 如果当前计数大于零,则它将递减。 如果新计数为零,则所有等待的线程都将被重新启用以进行线程调度。
      • 如果当前计数等于零,那么没有任何反应。
       

 (3)getcount()

 (4)await()

    • await()

      导致当前线程等到锁存器计数到零,除非线程是 interrupted

    • await(long timeout, TimeUnit unit)

      导致当前线程等到锁存器向下计数到零,除非线程为interrupted ,否则指定的等待时间过去。

      如果当前计数为零,则此方法将立即返回值为true

      如果当前计数大于零,则当前线程将被禁用以进行线程调度,并处于休眠状态,直至发生三件事情之一:

      •  如果计数达到零,则方法返回值为true

      • 一些其他线程interrupts当前线程;

      • 要么指定的等待时间过去了。

3.示例

多人开会,人到齐了才能开始开会。

人员类:

public class Participater implements Runnable {
    private String name;
    private Conference conference;

    public Participater(String name, Conference conference) {
        this.name = name;
        this.conference = conference;
    }

    @Override
    public void run() {
        conference.arrive(this.name);
    }
}

会议类:

public class Conference implements Runnable {
    private CountDownLatch downLatch;

    public Conference(int count) {
        this.downLatch = new CountDownLatch(count);
    }

    public void arrive(String name) {
        System.out.println(name + "到达。");
        //计数器减一
        downLatch.countDown();
        System.out.println("会议等待开始,还有" + downLatch.getCount() + "没有到...");

    }

    @Override
    public void run() {
        System.out.println("会议开始,参加会议的人数为:" + downLatch.getCount());
        try {
            //等待所有人到达,即计数器为0
            downLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("所有人已到齐,开始开会.....");
    }
}

测试类:

public class Test {

    public static void main(String[] args) {
        //会议人数
        int count = 3;
        //开启会议室线程,等待开会
        Conference conference = new Conference(count);
        new Thread(conference).start();
        //开启三个成员线程,参加会议
        Stream.iterate(1,item -> item + 1).limit(count)
                .forEach(item -> new Thread(new Participater("person_" + item,conference)).start());

    }
}

测试结果:

4.补充

       如果参加会议的有一个人一直没有来的话,那总不能一直等下去吧。这里就需要用到了await的重载方法,等到一定时间等不到了就直接开始开会。

二 CyclicBarrier

1.定义

  • 允许一组线程全部等待彼此达到共同屏障点的同步辅助。 循环阻塞在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。 屏障被称为循环 ,因为它可以在等待的线程被释放之后重新使用。

2.基本方法

(1)构造方法

(2)基本方法

3.示例

任务类:

public class ThreadTest extends Thread {
    private CyclicBarrier cyclicBarrier;

    public ThreadTest(CyclicBarrier cyclicBarrier) {
        this.cyclicBarrier = cyclicBarrier;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "达到.....");
        try {
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "执行完成");
    }
}

测试类:

public class CyclicBarrierTest {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
            @Override
            public void run() {
                System.out.println("执行CyclicBarrier中的任务.....");
            }
        });
        for (int i = 0;i < 5;i++) {
            new Thread(new ThreadTest(cyclicBarrier)).start();
        }
        
    }

}

测试结果:

猜你喜欢

转载自blog.csdn.net/qq_31689009/article/details/106680728