Java Concurrency: Condition Interface

Lock mating interface Condition realized wait / notification mode, the monitor and Object methods (wait, notify, notifyAll method, etc.), are realized wait / notification mode, but this mode of use, and both of the features there are still differences on.

Comparison Condition and method of Object monitor interface
Comparison items Object Monitor Methods Condition
Pre-conditions Acquiring an object lock

Call Lock.lock () acquires the lock

Call Lock.newCondition () Gets Condition objects

Called Direct calls, such as: Object.wait () Direct calls, such as: condition.await ()
The number of waiting queue One More
The current thread releases the lock and enter the wait state stand by stand by

The current thread releases the lock and enter the wait state,

In the waiting state does not respond to interrupts

not support stand by
The current thread releases the lock and enter the timeout wait state stand by stand by
The current site to release the lock and enter the wait state to some future time not support stand by
Wake up a thread waiting in the queue stand by stand by
Wake up all threads waiting in the queue stand by stand by

Object model in monitoring, an object has a synchronous queue and a wait queue, and the AQS has a plurality of synchronous queue and queues waiting.

Object monitoring model:

Synchronization of the queue and wait queue Condition:

 

Description Method and Condition section:

Method name description
void await() throws
InterruptedException

The current thread into a wait state until notification (signal) or interrupted,

The current thread will enter the run state and await from this method returns (show

The thread has acquired Condition objects corresponding lock), including:

Other threads (call interrupt () method interrupts the current thread) calls

Condition of the signal () or signalAll () method, and the current line

Cheng was selected wake

void awaitUninterruptibly()
The current thread into the wait state, know to be notified, insensitive to interrupt
long awaitNanos(long nanosTimeout)
throws InterruptedException

The current thread into a wait state until it is notified, interrupted or timed out,

Return value represents the remaining time, nanosTimeout nanoseconds if

Before being awakened, the return value is (nanosTimeout -  actual time-consuming).

If the return is zero or negative, it timed out.

boolean awaitUntil(Date deadline)

The current thread into a wait state until it is notified, interrupted, or to a

time. Not to a specific time to be notified, returns true; otherwise,

Return false

void signal()

Wake up on a waiting Condition thread, the thread from waiting methods

Condition must acquire the lock associated with the return of former

void signalAll()

Wakes up all waiting on the Condition of threads from the wait method can

Returned thread must acquire the lock associated with Condition

Condition of realization

① waiting queue

Synchronous queue and wait queue in front of the Condition of each node in the queue contains a reference to the thread, the thread is waiting on the object Condition threads, if a thread calls Condition.await () method, then the thread will be released lock, configured to join the waiting queue node enters the wait state. Synchronous queue and wait queue node types are static in inner class Node AQS. Condition is static inner classes of AQS.

② wait

Condition of the await method calls, make the current thread into the wait queue and release the lock, but the thread state to wait state. When returning from await method, the current thread must acquire the lock associated with Condition.

 1     public final void await() throws InterruptedException {
 2             if (Thread.interrupted())
 3                 throw new InterruptedException();
 4             Node node = addConditionWaiter();    // 当前线程加入等待队列
 5             int savedState = fullyRelease(node);  // 释放同步状态,也就是释放锁
 6             int interruptMode = 0;
 7             while (!isOnSyncQueue(node)) {
 8                 LockSupport.park(this);
 9                 if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
10                     break;
11             }
12             if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
13                 interruptMode = REINTERRUPT;
14             if (node.nextWaiter != null) // 线程被取消的话要清除节点
15                 unlinkCancelledWaiters();
16             if (interruptMode != 0)
17                 reportInterruptAfterWait(interruptMode);
18         }

 

如果队列的角度来看await()方法,当调用await()方法时,相当于把同步队列的首节点(获取了锁的节点)移动到Condition的等待队列中,实际上是通过addConditionWaiter()方法把当前线程构造成一个新的节点并将其加入等待队列中。

③ 通知

调用该方法的前置条件是要获取了锁,方法首先用isHeldExclusively()检查,接着获取等待队列的首节点,将其移动到同步队列并使用LockSupport工具类唤醒节点中的线程。

1     public final void signal() {
2             if (!isHeldExclusively())
3                 throw new IllegalMonitorStateException();
4             Node first = firstWaiter;
5             if (first != null)
6                 doSignal(first);
7         }
1     private void doSignal(Node first) {
2             do {
3                 if ( (firstWaiter = first.nextWaiter) == null)
4                     lastWaiter = null;
5                 first.nextWaiter = null;
6             } while (!transferForSignal(first) &&
7                      (first = firstWaiter) != null);
8     }
 1     final boolean transferForSignal(Node node) {
 2         /*
 3          * 如果无法更改waitStatus,则该节点会被取消
 4          */
 5         if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
 6             return false;
 7 
 8         /*
 9          * 拼接到队列上并尝试设置前任的waitStatus以指示线程(可能)正在等待。
10          * 如果取消或尝试设置waitStatus失败,请唤醒以重新同步
11          * (在这种情况下,waitStatus可能是暂时性且无害的错误)
12          */
13         Node p = enq(node);
14         int ws = p.waitStatus;
15         if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
16             LockSupport.unpark(node.thread);
17         return true;
18     }

节点从等待队列移动到同步队列:

 

Guess you like

Origin www.cnblogs.com/magic-sea/p/11594861.html