Arrayblockingqueue source reading and analysis
By the name of this class, you can know that Arrayblockingqueue is a bottom-up use array implementation, with queue characteristics of the first-in-one and thread-safe a collection class, he can also achieve a specified time of blocking read and write, which can solve the problem of producer consumers blocking queue.
First look at how it is constructed:
public arrayblockingqueue (int capacity) {
This (capacity, false);
}
public arrayblockingqueue (int capacity, Boolean fair) {
if (capacity <= 0)
Throw Newillegalargumentexception ();
This.items = newobject[capacity];
Lock = Newreentrantlock (FAIR);
Notempty =lock.newcondition ();
Notfull = Lock.newcondition ();
}
This is the first two construction methods, you can find the problem is that it does not have a default constructor, the passed parameter is the size of the created array of objects, while initializing the lock and two condition of this lock, a notempty, as the queue empty, take the wait for the operation The other is Notfull, which is the wait for the put operation when the queue is full.
First, let's look at the offer method, which has two overloaded implementations for inserting elements into the tail of an array.
Let's take a look at the offer method without parameters:
Lock.lock ();
try {
if (Count ==items.length)
return false;
else {
Insert (e);
return true;
}
} finally {
Lock.unlock ();
}
Where count is the number of elements in the queue, items is an array of stored values, and when the array is full, it does not enter the wait, but returns false directly. In case of dissatisfaction, the Insert method will be entered, the Notempty.signal () will be executed, and the thread waiting for take operation to wake up the queue is empty
It also has an overloaded method with three parameters, the array is full, then goes into wait until the following three cases continue: wake up, reach the specified time, or the current thread is interrupted (interrupt). This method first converts the specified time to nanoseconds, and then performs a lock operation, such as an array that is not full, returns False if the object is full and exceeds the specified time, or if the specified time is not exceeded, the awaitnanos of Notfull condition is called. Method waits, such as to be awakened or timed out, to continue to determine whether the array is full, or if the thread is interrupt, to throw interruptedexception directly.
And look at the put method.
The specific code is as follows:
public void put (e e) throwsinterruptedexception {
Checknotnull (e);
Final Reentrantlock lock = This.lock;
Lock.lockinterruptibly ();
try {
while (count = = items.length)
Notfull.await ();
Insert (e);
} finally {
Lock.unlock ();
}
}
As you can see, this method waits until the array is full, until the array is not empty or the thread is interrupt.
Let's take a look at the poll method, which is used to get the first element in the queue. As with an offer, there are two overloads.
Public E poll () {
Final reentrantlocklock = This.lock;
Lock.lock ();
try {
Return (Count ==0)? Null:extract ();
} finally {
Lock.unlock ();
}
}
This is the poll method without the time parameter, which will not go into wait if the number of elements in the array is zero, but instead directly return null, do not empty the extract () method, execute the Notfull.signal (), and wake up the put blocking thread.
There is also a poll (E,long,timeunit) method with three parameters. If there are no elements in the queue, the wait is entered, the same as the offer (E,long,timeunit), and it continues after three cases. First converts the specified time to nanoseconds and locks, the number of elements in an array is nonzero, gets the last element from the current set of objects, sets the element at that location to null after fetching, and the number of elements in an array is zero, first determining whether the remaining wait time is less than 0, or if less than the return NULL, such as greater than the call to Notempty condition's Awaitnanos method to wait, such as to be awakened or timed out, continue to determine whether the number of elements in the array is not zero, such as the thread is interrupt, is thrown directly Interruptedexception.
Finally, take a look at the take method, the source code is as follows:
Publice take () throws Interruptedexception {
Final Reentrantlock lock = This.lock;
Lock.lockinterruptibly ();
try {
while (count = = 0)
Notempty.await ();
return extract ();
} finally {
Lock.unlock ();
}
}
As you can see, the Take method is called, and the method waits until the array is empty, until the array is not empty or the thread is interrupt. Then call the Extract method and take out the elements of the first team.
Arrayblockingqueue Source Reading and analysis