Java并发编程 —— 同步工具类-闭锁(CountDownLatch)、信号量(Semaphore)、栅栏(CyclicBarrier)

本文详细解析Java并发编程中的闭锁CountDownLatch、信号量Semaphore和栅栏CyclicBarrier。CountDownLatch用于阻塞线程直到其他线程完成特定任务;Semaphore通过许可证管理线程访问资源数量;CyclicBarrier让一组线程到达屏障后一起继续执行。文章通过源码分析并提供实例代码链接,帮助理解这些同步工具类的工作原理和使用场景。
摘要由CSDN通过智能技术生成

1. 引言

之前对同步工具类闭锁CountDownLatch、信号量Semaphore、栅栏CycliBarrier有过了解,但是对其原理还不是清晰,在此从源码角度进行分析。

详细的实例代码地址:https://github.com/yq-debug/JavaExercise/tree/master/src/main/java/juc_sync

2. CountDownLatch

//允许一个线程或多个线程等待,直到其他线程的操作完成
public class CountDownLatch {
   
   
    //Sync类继承自AQS类
    private static final class Sync extends AbstractQueuedSynchronizer {
   
        private static final long serialVersionUID = 4982264981922014374L;
        //初始化Sync类
        Sync(int count) {
   
            setState(count);//设置同步状态
        }
        //获取同步状态
        int getCount() {
   
            return getState();
        }
        
        protected int tryAcquireShared(int acquires) {
   
            return (getState() == 0) ? 1 : -1;
        }

        protected boolean tryReleaseShared(int releases) {
   
             
            for (;;) {
   
                int c = getState();
                if (c == 0)
                    return false;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }
    }

    private final Sync sync;
    
    //构造一个含有count的锁存器的对象
    public CountDownLatch(int count) {
   
        if (count < 0) throw new IllegalArgumentException("count < 0");
        //初始化sync对象,此时传入的是锁存器的数量
        this.sync = new Sync(count);
    }

    //阻塞当前线程直到线程阻塞器的计数为0
    public void await() throws InterruptedException {
   
        sync.acquireSharedInterruptibly(1);
    }

    //阻塞当前线程直到线程阻塞器的计数为0
    public boolean await(long timeout, TimeUnit unit)
        throws InterruptedException {
   
        return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
    }

    //减少锁存器的数量
    public void countDown() {
   
        sync.releaseShared(1);
    }

    //返回当前锁存器的数量
    public long getCount() {
   
        return sync.getCount();
    }

    //返回此闭锁的字符串表示
    public String toString() {
   
        return super.toString() + "[Count = " + sync.getCount() + "]";
    }
}

2.1. 理解

  1. CountDownLatch的作用是阻塞当前线程,直到其他线程操作完成之后,即闭锁中锁存器的数量为0时,再激活当前线程继续执行,与join()方法类似,都是将并行线程变为串行线程。

  2. 闭锁CountDownLatch在初始化的时候会传入一个参数,表示锁存器的数量,即代表要阻塞的线程的数量。

  3. 需要后执行的线程先进行阻塞,需要先行执行的线程在执行完之后将锁存器的数量减1,直到锁存器的数量为0或者时间超时触发阻塞线程执行。

此处使用的两个方法:countDown()锁存器的数量减1, await()阻塞当前线程直到锁存器的数量为0

  1. 使用场景:当线程的执行执行结果与执行顺序有关时(即会出现竞争冲突)则采用闭锁CountDownLatch使并发线程变为串行线程执行。

  2. CountDownLatch的底层实现是AQS类

3. Semaphore

 
public class Semaphore implements java.io.Serializable {
   
    private static final long serialVersionUID = -3222578661600680210L;
    
    private final Sync sync;

    abstract static class Sync extends AbstractQueuedSynchronizer {
   
        private static final long serialVersionUID = 1192457210091910933L;

        Sync(int permits) {
   
            
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值