深入浅出JUC常用同步器

1.JUC下同步器

   日常开发会遇到主线程开启多个子线程去并行执行任务,并且主线程需要等待所有子线程执行完后在进行汇总的场景。
   同步器出现之前,通常采用Thread.join()方法来实现,join方法不够灵活,JDK大佬就在JUC下新建了几个同步器,底层都是基于AQS实现。
   关于AQS可以看看这篇一文带你看懂Java多线程并发,深度剖析AQS源码

下面就针对JUC下三种常见同步器进行简要介绍。

1.1 CountdownLatch 倒计数锁存器

这个同步器相对比较简单,先使用构造方法初始化共享锁数count,然后每次调用countDown()方法, 内部调用sync.releaseShared(1)释放一把锁,锁数减一,直到锁Count等于0则会唤醒之前使用await()方法阻塞的线程。

先看这个tryReleaseShared()方法

	    public void countDown() {
   
   
	        sync.releaseShared(1);
	    }
        public final boolean releaseShared(int arg) {
   
   
        if (tryReleaseShared(arg)) {
   
   
            signalNext(head);
            return true;
        }
        return false;
    }
    	// 着重看这个方法
        protected boolean tryReleaseShared(int releases) {
   
   
            // Decrement count; signal when transition to zero
            for (;;) {
   
   
            	// 当前锁数
                int c = getState();
                // 锁已经为0 则不在执行减一,避免多线程下重复减一到负数
                if (c == 0)
                    return false;
                // 锁减一
                int nextc = c - 1;
                // CAS操作原子性保证一个线程执行
                if (compareAndSetState(c, nextc))
                	// 如果为0则为true那么将执行signalNext(head)方法
                    return nextc == 0;
            }
        }
       // h 参数为head 头结点。 
    private static void signalNext(Node h) {
   
   
        Node s;
        // 如果头结点下一个节点不为空。
        if (h != null && (s = h.next) != null && s.status != 0) {
   
   
        	// 取消WAITTING状态 转为唤醒状态
            s.getAndUnsetStatus(WAITING);
            // 唤醒s节点所对应的线程。
            LockSupport
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值