CountDownLatch、Semaphore和CyclicBarrier的学习

CountDownLatch、Semaphore和CyclicBarrier的学习

 

JAVA并发包中有三个类用于同步一批线程的行为,分别是CountDownLatch、Semaphore和CyclicBarrier。

  • CountDownLatch

CountDownLatch是一个计数器闭锁,主要的功能就是通过await()方法来阻塞住当前线程,然后等待计数器减少到0了,再唤起这些线程继续执行。 这个类里主要有两个方法,一个是向下减计数器的方法:countdown()

import java.util.concurrent.CountDownLatch;

/**
 * @Auther: huanglong
 * @Date: 2019/1/3 16:30
 * @Description:
 */
public class TestCountDownLatch {


    public static void main(String[] args) throws InterruptedException {


        final CountDownLatch begin = new CountDownLatch(1);
        final CountDownLatch end = new CountDownLatch(10);
        for (int i = 0 ;i < 10;i++ ){
            new Thread(new Player(begin,end),"player" + i).start();
        }
        System.out.println("Game Start");
        begin.countDown();
        end.await();
        System.out.print("Game Over");

    }

}
class Player implements Runnable{
    // 开始的倒数锁
    private  final CountDownLatch begin ;
    // 结束的倒数锁
    private final CountDownLatch end;

    Player(CountDownLatch begin, CountDownLatch end) {
        this.begin = begin;
        this.end = end;
    }

    @Override
    public void run() {
        try {
            // 如果当前计数为零,则此方法立即返回。
            // 等待
            begin.await();
            Thread.sleep((long) (Math.random() * 10000));
            System.out.println(Thread.currentThread().getName() + " arrived");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 每个选手到达终点时,end就减一
            end.countDown();
        }
    }
}

 测试结果为

Game Start
player8 arrived
player1 arrived
player6 arrived
player7 arrived
player2 arrived
player9 arrived
player5 arrived
player0 arrived
player3 arrived
player4 arrived
Game Over

CountDownLatch是一个同步的辅助类,允许一个或多个线程,等待其他一组线程完成操作,再继续执行。

个人理解:CountDownLatch 可以理解为倒计时计数,比如多个游戏参与者,每个游戏参与者的角色死亡之后 ,游戏才算结束。

  • Semaphore

Semaphore与CountDownLatch相似,不同的地方在于Semaphore的值被获取到后是可以释放的,并不像CountDownLatch那样一直减到底。它也被更多地用来限制流量,类似阀门的 功能。如果限定某些资源最多有N个线程可以访问,那么超过N个主不允许再有线程来访问,同时当现有线程结束后,就会释放,然后允许新的线程进来。

import java.util.concurrent.Semaphore;

/**
 * @Auther: huanglong
 * @Date: 2019/1/3 16:30
 * @Description:
 */
public class TestSemaphore {


    public static void main(String[] args) throws InterruptedException {


        //允许并行最大线程数
        final Semaphore max = new Semaphore(5,true);
        System.out.println("Test Start\n");
        for (int i = 0 ;i < 10;i++ ){
            new Thread(new Reader(max),"Reader" + i).start();
        }
    }

}

class Reader implements Runnable{

    //
    private  final Semaphore max ;


    Reader(Semaphore max) {
        this.max = max;
    }

    @Override
    public void run() {
        try {
            //获取资源执行
            max.acquire();
            System.out.println(Thread.currentThread().getName() + " --in Room");
            Thread.sleep((long) (Math.random() * 10000));

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //执行完毕释放资源
            max.release();
            System.out.println(Thread.currentThread().getName() + " --leave Room");
        }
    }
}

结果:

Test Start

Reader2 --in Room
Reader6 --in Room
Reader1 --in Room
Reader5 --in Room
Reader9 --in Room
Reader1 --leave Room
Reader0 --in Room
Reader2 --leave Room
Reader4 --in Room
Reader6 --leave Room
Reader8 --in Room
Reader5 --leave Room
Reader3 --in Room
Reader3 --leave Room
Reader7 --in Room
Reader0 --leave Room
Reader9 --leave Room
Reader7 --leave Room
Reader4 --leave Room
Reader8 --leave Room

个人理解:跟 CountDownLatch 类似,但计数可以可以重置,类似游乐园,有最大容量限制,到达最大容量限制,就不允许进入了。

  • CyclicBarrier

CyclicBarrier是用来一个关卡来阻挡住所有线程,等所有线程全部执行到关卡处时,再统一执行下一步操作,它里面最重要的方法是await()方法

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;

/**
 * @Auther: huanglong
 * @Date: 2019/1/3 16:30
 * @Description:
 */
public class TestCyclicBarrier {


    public static void main(String[] args) throws InterruptedException {


        final CyclicBarrier barrier = new CyclicBarrier(5, new Runnable() {
            @Override
            public void run() {
                System.out.println("所有工作完成!");
            }
        });
        System.out.println("Test Start\n");
        for (int i = 0 ;i < 5;i++ ){
            new Thread(new Tool(barrier),"Tool" + i).start();
        }

    }
}

class Tool implements Runnable{


    private  final CyclicBarrier condition ;


    Tool(CyclicBarrier condition) {
        this.condition = condition;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + " 工作完成!");
            condition.await();
            Thread.sleep((long) (Math.random() * 10000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

执行结果

Test Start

Tool0 工作完成!
Tool1 工作完成!
Tool4 工作完成!
Tool3 工作完成!
Tool2 工作完成!
所有工作完成!


个人理解:比如车辆制造,有很多模块可以同时制造,但是有的模块简单速度快,建造完毕后仍然等待其他模块一起完成才能组装成一辆车。

 

以上只是初步理解,具体细节以后探讨,做此记录,防止忘记

参考其他资料

https://blog.csdn.net/yanhandle/article/details/9016329

https://blog.csdn.net/chenchaofuck1/article/details/51596786

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值