CountDownLatch、CyclicBarrier和Semaphore使用

  • CountDownLatch

CountDownLatch是用来线程计数的。等待一组线程全部执行完后再本线程继续执行。如:A线程需要等待B、C和D(由初始化CountDownLatch参数觉得等待多少个线程)线程执行完后再执行。

主要的方法:

// 构造方法,count决定等待多少个线程
public CountDownLatch(int count)
// 等待线程完成数减1
public void countDown()
// 调用await本线程会挂起,当等待线程未完成数为0,即countDown调用次数等于构造方法参数值时会被唤醒
public void await()
public boolean await(long timeout, TimeUnit unit)

以下是CountDownLatch的用法:

public class CountDownLatchTest {
    public static void main(String[] args) {
        final CountDownLatch countDownLatch = new CountDownLatch(2);
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                try {
                    String name = Thread.currentThread().getName();
                    System.out.println("子线程" + name + "正在运行中......");
                    TimeUnit.SECONDS.sleep(5);
                    System.out.println("子线程" + name + "执行完毕");
                    countDownLatch.countDown();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }

        try {
            System.out.println("======等待两个子线程执行完毕");
            // 只有子线程执行完毕个数等于CountDownLatch初始化个数才会继续执行await后面代码
            countDownLatch.await();
            System.out.println("两个子线程都执行完毕!!!!!!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("主线程继续执行中。。。。。。。。");
    }
}

结果:

子线程Thread-0正在运行中......
======等待两个子线程执行完毕
子线程Thread-1正在运行中......
子线程Thread-1执行完毕
子线程Thread-0执行完毕
两个子线程都执行完毕!!!!!!
主线程继续执行中。。。。。。。。
  • CyclicBarrier

CyclicBarrier 设置一个障碍点,让同组线程到达改点的线程等待本组未达到该点的线程,同组全部线程到达该点才越过障碍物释放资源,让其它组循环利用该对象。

主要方法:

// 构造方法设置同组线程数
public CyclicBarrier(int parties)
// 构造方法设置同组线程数;全部达到障碍物时执行barrierAction函数
public CyclicBarrier(int parties, Runnable barrierAction)
// 某个线程调用await时挂起,需要等同组所有线程到达才能唤醒
public int await() throws InterruptedException, BrokenBarrierException

以下是 CyclicBarrier 的用法:

/**
 * Created on 18/3/15 14:40.
 *
 * @author wolf
 */
public class CyclicBarrierTest {
    public static void main(String[] args) {
        int n = 3;
        CyclicBarrier barrier = new CyclicBarrier(n);
        for (int i = 0; i < 3; i++) {
            new Worker(barrier).start();
        }

        try {
            TimeUnit.SECONDS.sleep(6);
            System.out.println("--------讨厌的循环利用分割线------------");
        } catch (Exception e) {
            e.printStackTrace();
        }

        for (int i = 0; i < n; i++) {
            new Worker(barrier).start();
        }
    }

    static class Worker extends Thread {
        private CyclicBarrier barrier;
        public Worker(CyclicBarrier barrier) {
            this.barrier = barrier;
        }
        @Override
        public void run() {
            long startTime = System.currentTimeMillis();
            String name = Thread.currentThread().getName();
            System.out.println("线程 " + name + " 正在执行任务.......");
            try {
                int time = RandomUtils.nextInt(1, 5);
                TimeUnit.SECONDS.sleep(time);
                System.out.println("线程 " + name + " 执行任务完毕!!!用时:" + time);
                barrier.await();
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("线程 " + name + " 全部耗时:"+(System.currentTimeMillis()-startTime));
        }
    }
}
  • Semaphore

Semaphore 通过名字我们就知道这个计算信号量,也就是控制获取资源的许可证。

主要的方法:

// 构造方法设置可用资源的数量,即许可证的数量
public Semaphore(int permits)
// 构造方法设置可用资源的数量,即许可证的数量,fair 是否公平获得许可证,默认是先来后到公平的
public Semaphore(int permits, boolean fair)
// 同步获取许可证,
public void acquire() throws InterruptedException
// 尝试获取许可证,结果直接返回
public boolean tryAcquire()
// 尝试获取许可证,结果等待时间超时直接返回
public boolean tryAcquire(long timeout, TimeUnit unit)
// 释放许可证,可给其它等待线程使用
public void release()

以下是 Semaphore 用法:

public class SemaphoreTest {
    public static void main(String[] args) {
        int no = 5;
        Semaphore semaphore = new Semaphore(2);
        for (int i = 0; i < no; i++) {
            new Worker(i, semaphore).start();
        }
    }
    static class Worker extends Thread {
        private int no;
        private Semaphore semaphore;
        public Worker(int no, Semaphore semaphore) {
            this.no = no;
            this.semaphore = semaphore;
        }
        @Override
        public void run() {
            try {
                long startTime = System.currentTimeMillis();
                semaphore.acquire();
                System.out.println("worker " + this.no + " 获取许可证,开始工作....");
                int time = RandomUtils.nextInt(1, 5);
                TimeUnit.SECONDS.sleep(time);
                semaphore.release();
                System.out.println("worker " + this.no + " 完成工作,释放许可证!耗时:" + (System.currentTimeMillis() - startTime));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

原文地址:https://www.cnblogs.com/wolf-bin/p/8576787.html

时间: 2024-10-07 10:59:28

CountDownLatch、CyclicBarrier和Semaphore使用的相关文章

Join,CountDownLatch,CyclicBarrier,Semaphore和Exchanger

CountDownLatch允许一个或者多个线程等待其他线程完成操作,之后再对结果做统一处理: 适用场景,分布式系统中对多个微服务的调用,并发执行并且必须等待全部执行完成才能继续执行后续操作: 其实在java中默认的实现是join()方法,join()方法主要的作用是当前线程必须等待直到join线程执行完成之后才能继续执行后续的操作, 其本质就是轮询判断join线程是否存活,如果存活则主线程继续等待,否则,通过调用this.notifyAll()方法来继续执行主线程. 实例代码如下: publi

Java并发编程:CountDownLatch、CyclicBarrier和Semaphore

在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下是本文目录大纲: 一.CountDownLatch用法 二.CyclicBarrier用法 三.Semaphore用法 若有不正之处请多多谅解,并欢迎批评指正. 请尊重作者劳动成果,转载请标明原文链接: http://www.cnblogs.com/dolphin0520/p/3920397.htm

并发工具类:CountDownLatch、CyclicBarrier、Semaphore

在多线程的场景下,有些并发流程需要人为来控制,在JDK的并发包里提供了几个并发工具类:CountDownLatch.CyclicBarrier.Semaphore. 一.CountDownLatch 1 import java.util.concurrent.CountDownLatch; 2 3 4 public class CountDownLatchTest 5 { //设置N为2 6 static CountDownLatch c = new CountDownLatch(2); 7 p

Java并发之CountDownLatch、CyclicBarrier和Semaphore

CountDownLatch 是能使一组线程等另一组线程都跑完了再继续跑:CyclicBarrier 能够使一组线程在一个时间点上达到同步,可以是一起开始执行全部任务或者一部分任务. 这次说一下 JUC 中的同步器三个主要的成员:CountDownLatch.CyclicBarrier 和 Semaphore(不知道有没有初学者觉得这三个的名字不太好记).这三个是 JUC 中较为常用的同步器,通过它们可以方便地实现很多线程之间协作的功能.(下面的代码出自 JDK 文档) CountDownLat

使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程

在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.CountDownLatch用法 CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能.比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了. CountDownLatch类只提

Java多线程:CountDownLatch、CyclicBarrier 和 Semaphore

场景描述: 多线程设计过程中,经常会遇到需要等待其它线程结束以后再做其他事情的情况,比如多线程下载文件,每个线程都会下载文件的一部分,在所有线程结束以后,需要将各部分再次拼接成一个完整的文件. 有几种方案: 1.在主线程中设置一自定义全局计数标志,在工作线程完成时,计数减1.主线程侦测该标志是否为0,一旦为0,表示所有工作线程已经完成. 2.使用Java标准的类CountDownLatch来完成这项工作,原理是一样的,计数. CountDownLatch 一个同步辅助类,在完成一组正在其他线程中

多线程-CountDownLatch,CyclicBarrier,Semaphore,Exchanger,Phaser

CountDownLatch 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待.用给定的计数初始化CountDownLatch.调用countDown()计数减一,当计数到达零之前await()方法会一直阻塞,计数无法被重置. public class CountDownLatch { private final Sync sync; public CountDownLatch(int count); public void countDown() { syn

Java并发编程:CountDownLatch、CyclicBarrier和Semaphore (总结)

下面对上面说的三个辅助类进行一个总结: 1)CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同: CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行: 而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行: 另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的. 2)Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权

并发包下常见的同步工具类详解(CountDownLatch,CyclicBarrier,Semaphore)

目录 1. 前言 2. 闭锁CountDownLatch 2.1 CountDownLatch功能简介 2.2 使用CountDownLatch 2.3 CountDownLatch原理浅析 3.循环屏障CyclicBarrier 3.1 CyclicBarrier功能简介 3.2 使用CyclicBarrier 3.3 CyclicBarrier原理浅析 4. 信号量Semaphore 4.1 Semaphore功能简介 4.2 使用Semaphore进行最大并发数的控制 4.3 Semaph

Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore

在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法. 以下是本文目录大纲: 一.CountDownLatch用法 二.CyclicBarrier用法 三.Semaphore用法 一.CountDownLatch用法 CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能.比如有一个任务A,它要等待其他