JUC-AQS的应用

本文深入探讨了Java并发控制工具Semaphore、CyclicBarrier的原理和使用方法。Semaphore用于限制同时访问特定资源的线程数量,而CyclicBarrier则允许一组线程等待彼此到达某个屏障点。在CyclicBarrier中,所有线程到达屏障点后才能继续执行,适合多线程计算数据并合并结果的场景。文章通过示例展示了如何在并发编程中有效利用这两个工具来提升程序效率。
摘要由CSDN通过智能技术生成

闭锁

由于设定了state为一个整数大于0的值,全部进入同步队列;

public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }

countdownDown

public void countDown() {
        sync.releaseShared(1);
    }

直接将state置为0;

protected boolean tryReleaseShared(int releases) {
            // Decrement count; signal when transition to zero
            for (;;) {
                int c = getState();
                if (c == 0)
                    return false;
                int nextc = c-1;
                if (compareAndSetState(c, nextc))
                    return nextc == 0;
            }
        }

会唤醒第一个节点,而共享模式下会依次唤醒后续节点

Semaphore

读锁
和上相比,state也是一样的,
不过请求的时候,如果请求到了直接就通过了,cas成功就直接通过,知道state小于0,挂起线程;

  final int nonfairTryAcquireShared(int acquires) {
            for (;;) {
                int available = getState();
                int remaining = available - acquires;
                if (remaining < 0 ||
                    compareAndSetState(available, remaining))
                    return remaining;
            }
        }

//小于0了直接进入同步队列,除了头节点全部挂起,直到信号量又有了,

private void doAcquireSharedInterruptibly(int arg)

释放的时候又会加state,

protected final boolean tryReleaseShared(int releases) {
            for (;;) {
                int current = getState();
                int next = current + releases;
                if (next < current) // overflow
                    throw new Error("Maximum permit count exceeded");
                if (compareAndSetState(current, next))
                    return true;
            }
        }

CyclicBarrier

重入锁+等待队列

CyclicBarrier barrier = new CyclicBarrier(令牌数量);  
barrier.await();//屏障点,消耗一个令牌,当令牌消耗到任务数量的时候,栅栏就会全部放开  
barrier.reset();//重置,可以复用栅栏,不用重新创建栅栏对象  
private int dowait(boolean timed, long nanos)
        throws InterruptedException, BrokenBarrierException,
               TimeoutException {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            final Generation g = generation;

            if (g.broken)
                throw new BrokenBarrierException();

            if (Thread.interrupted()) {
                breakBarrier();
                throw new InterruptedException();
            }

            int index = --count;
            if (index == 0) {  // tripped
                boolean ranAction = false;
                try {
                    final Runnable command = barrierCommand;
                    if (command != null)
                        command.run();
                    ranAction = true;
                    nextGeneration();
                    return 0;
                } finally {
                    if (!ranAction)
                        breakBarrier();
                }
            }

阑珊的应用

CyclicBarrier 的应用场景:

  • CyclicBarrier 可以用于多线程计算数据,最后合并计算结果的场景。例如:用一个 Excel
  • 保存了用户所有银行流水,每个 Sheet 保存一个账户近一年的每笔银行流水,现在需要统计
  • 用户的日均银行流水,先用多线程处理每个 Sheet 里面的银行流水,都执行完之后,得到每个
  • Sheet 的日均银行流水,最后,再用 barrierAction 用这些线程的计算结果,计算出整个
  • Excel 的日均银行流水
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值