zoukankan      html  css  js  c++  java
  • AQS 中的条件

    按照我看源码的进度,条件 condition 是 aqs 的最后一块拼图。

    我总结的 aqs 三要素:
    state
    ownerThread
    等待队列

    这里没有考虑到 condition,condition 的用法如下

    lock.lock();
      condition.await(t);
    
    lock.unlock();

    借助 AbstractQueuedSynchronizer.ConditionObject#await(long, java.util.concurrent.TimeUnit)
    来分析条件队列,这个方法会挂起线程,一段时间后自动醒来,不需要其他线程唤醒。

    await(t) 要做哪些事?

    整体来看,要做两件事:
    一、释放锁,挂起线程
    二、当线程醒来,重新获取锁

    细分步骤:

    1. 只有持有了锁,才能做 await(t)
    2. 把当前线程加入到条件队列中
    3. 重置 state 值为 0,并唤醒等待队列中的节点(这个动作其实就是释放锁)
    4. 不考虑自旋时间,直接挂起线程 t 时间
    5. 等待 t 时间后,线程被 os 唤醒,把线程所在的节点从条件队列取出,放入等待队列,线程需要重新获取锁

    // java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject#await(long, java.util.concurrent.TimeUnit)
    public final boolean await(long time, TimeUnit unit)
            throws InterruptedException {
        long nanosTimeout = unit.toNanos(time);
        if (Thread.interrupted())
            throw new InterruptedException();
        Node node = addConditionWaiter();
        int savedState = fullyRelease(node);
        final long deadline = System.nanoTime() + nanosTimeout;
        boolean timedout = false;
        int interruptMode = 0;
        while (!isOnSyncQueue(node)) {
            if (nanosTimeout <= 0L) {
                timedout = transferAfterCancelledWait(node);
                break;
            }
            if (nanosTimeout >= spinForTimeoutThreshold)
                LockSupport.parkNanos(this, nanosTimeout);
            if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                break;
            nanosTimeout = deadline - System.nanoTime();
        }
        if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
            interruptMode = REINTERRUPT;
        if (node.nextWaiter != null)
            unlinkCancelledWaiters();
        if (interruptMode != 0)
            reportInterruptAfterWait(interruptMode);
        return !timedout;
    }
  • 相关阅读:
    ab Apache HTTP server benchmarking tool
    压缩JS的类
    看电影学人生:《白银帝国》有感
    JavaScript 闭包
    微软为asp.net ajax和jquery创建了CDN
    JavaScript工具
    Mysql初始化root密码和允许远程访问
    一步一步学Ruby(二十一):文件操作2
    测试包含HttpContext.Current的代码
    What’s the difference between <system.web> and <system.webServer>?
  • 原文地址:https://www.cnblogs.com/allenwas3/p/13215221.html
Copyright © 2011-2022 走看看