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;
    }
  • 相关阅读:
    UVA 11605 Lights inside a 3d Grid
    UVA 10288 Coupons
    UVA 11637 Garbage Remembering Exam
    阿里上市全解读【转载】
    C# 创建系统服务并定时执行【转载】
    Ehcache 整合Spring 使用页面、对象缓存
    详解 Tomcat 的连接数与线程池(转)
    Mysql主从热备
    centos上yum安装异常处理
    tomcat运行模式APR安装
  • 原文地址:https://www.cnblogs.com/allenwas3/p/13215221.html
Copyright © 2011-2022 走看看