Java多线程系列 JUC锁07 ConditionObject分析

ConditionObject是AQS中的内部类,提供了条件锁的同步实现,实现了Condition接口,并且实现了其中的await(),signal(),signalALL()等方法。

ConditionObject主要是为并发编程中的同步提供了等待通知的实现方式,可以在不满足某个条件的时候挂起线程等待。直到满足某个条件的时候在唤醒线程。

在一个AQS同步器中,可以定义多个Condition,只需要多次lock.newCondition(),每次都会返回一个新的ConditionObject对象。在ConditionObject中,通过一个等待队列来维护条线等待的线程。所以在一个同步器中可以有多个等待队列,他们等待的条件是不一样的。

条件队列

  条件队列是一个FIFO的队列,在队列的每个节点都包含了一个线程引用。该线程就是在Condition对象上等待的线程。这里的节点和AQS中的同步队列中的节点一样,使用的都是AbstractQueuedSynchronizer.Node类。每个调用了condition.await()的线程都会进入到条件队列中去。在Condition中包含了firstWaiter和lastWaiter,每次加入到条件队列中的线程都会加入到条件队列的尾部,来构成一个FIFO的条件队列。

方法分析

public final void await() throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        Node node = addConditionWaiter();  //把当前线程的节点加入到等待队列中
        int savedState = fullyRelease(node);  //由于调用await()方法的线程是已经获取了锁的,所以在加入到等待队列之后,需要去释放锁,并且唤醒后继节点线程
        int interruptMode = 0;
        while (!isOnSyncQueue(node)) {
            LockSupport.park(this);  //挂起当前线程,当别的线程调用了signal(),并且是当前线程被唤醒的时候才从park()方法返回
            if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
                break;
        }
        if (acquireQueued(node, savedState) && interruptMode != THROW_IE) //当被唤醒后,该线程会尝试去获取锁,只有获取到了才会从await()方法返回,否则的话,会挂起自己
            interruptMode = REINTERRUPT;
        if (node.nextWaiter != null) // clean up if cancelled
            unlinkCancelledWaiters();
        if (interruptMode != 0)
            reportInterruptAfterWait(interruptMode);
    }
View Code

猜你喜欢

转载自www.cnblogs.com/lizhouwei/p/9096710.html
今日推荐