Java blocking queue in ArrayBlockingQueue

table of Contents

1.ArrayBlockingQueue介绍

1.1BlockingQueue Interface

Interface BlockingQueue<E>

Supports blocking waiting queues: When removing the element, if the queue is empty, wait until the queue is not empty; when the storage element, if the queue is full, wait until the queue idle.

For BlockingQueue, performing operations when the conditions are not met, there are four forms.

 

Throws exception

Special value

Blocks

Times out

Insert

add(e)

(If the queue is not full, adding, return true;

If the queue is full, throw IllegalStateException)

offer(e)

(If the queue is not full, adding, return true;

If the queue is full, return false)

put(e)

(If the queue is not full, adding, no return value;

If the queue is full, wait until the queue has idle)

offer(e, time, unit)

(If the queue is not full, adding, return true;

If the queue is full, wait after a specified time or full queue, returns false)

Remove

remove()

(If the queue is not empty, removal, return true;

If the queue is empty, return false)

poll()

(If the queue is not empty, remove;

If the queue is empty, return null)

take()

(If the queue is not empty, remove;

If the queue is empty, wait until the queue is not empty)

poll(time, unit)

(If the queue is not empty, remove;

If the queue is empty, a specified time after the wait queue is empty, return null)

Examine

element()

peek()

not applicable

not applicable

Use the sample - typically (and more) producers, (multi) Consumer Model

// producer thread 
class Producer the implements the Runnable {
    Private  Final BlockingQueue Queue; // blocking queue 
   Producer (BlockingQueue Q) = {Queue Q;}
    public  void RUN () {
      the try {
        the while ( to true ) {queue.put (Produce () );} // production, incorporating team 
     } the catch (InterruptedException EX) {... handle ...} 
   } 
   Object produce () {...} 
 } 
// consumer thread 
 class consumer the implements Runnable {
    Private Final BlockingQueue Queue; // blocking queue 
   Consumer (BlockingQueue Q) = {Queue Q;}
    public  void RUN () {
      the try {
        the while ( to true ) {Consume (queue.take ());} // dequeued consumption 
     } the catch (InterruptedException EX) ... handle {...} 
   } 
   void Consume (Object X) {...} 
 } 
 class the Setup {
    void main () { 
     BlockingQueue Q = new new SomeQueueImplementation ();
   // start producers 1 thread, two consumer threads 
     Producer p =new Producer(q);
     Consumer c1 = new Consumer(q);
     Consumer c2 = new Consumer(q);
     new Thread(p).start();
     new Thread(c1).start();
     new Thread(c2).start();
   }
 } 

1.2ArrayBlockingQueue

ArrayBlockingQueue array is implemented thread safe bounded blocking queue.

1. Array Implementation: array implemented using a circular queue.

2. Thread safety: Use a ReentrantLock to ensure thread safety.

3. Bounded: a fixed number of elements may be stored. Due to internal array realization, once created, can not change the length of the array.

4. blocking queue: FIFO. When taken out of the element, if the queue is empty, wait until the queue is not empty; when the storage element, if the queue is full, wait until the queue is idle.

2.ArrayBlockingQueue source code analysis

2.1 Create

public ArrayBlockingQueue with ( int Capacity, Boolean Fair) {
     IF (Capacity <= 0 )
         the throw  new new an IllegalArgumentException ();
     the this .items = new new Object [Capacity]; // array storage elements 
    Lock = new new of ReentrantLock (Fair); // lock guarantee security thread 
    notEmpty = lock.newCondition (); 
    notFull =   lock.newCondition (); 
}

2.2 Producer Consumer Model

 

 

2.2.1 producers to produce elements --put method element into the team

put method

How to achieve synchronization between threads [producer] and [consumer]

1. If the queue is full, call notFull.await () method, the current thread is blocked waiting for [producer]

2. After the element into the team, calling notEmpty.signal () method, Wake blocked [consumer] thread

// inserts the specified element to the tail of the queue
 // If the queue is full, the current thread to wait until the queue is idle 
public  void PUT (E E) throws InterruptedException { 
    checkNotNull (E); 
    Final of ReentrantLock = Lock the this .lock;
   // get lock 
    lock.lockInterruptibly ();
     the try {
     // If the queue is full, the current thread to wait until the queue has idle 
        the while (COUNT == items.length) 
            notFull.await (); 
    // queue has idle elements into the team 
        enqueue (e ); 
    } the finally {
     // release lock 
        lock.unlock (); 
    } 
} 
 
Private void the enqueue (E X) {
     // Assert lock.getHoldCount () ==. 1;
     // Assert items [putIndex] == null;
   // element into the team 
    Final Object [] items = the this .items; 
    items [putIndex] = the X-;
     IF (++ putIndex == items.length) 
        putIndex = 0 ; 
    COUNT ++ ;
   // wake-up thread blocked on notEmepty 
    notEmpty.signal (); 
} 

 

2.2.2 --take consumer spending element method element from the team

take method

How to achieve [producer] and [consumer] Thread Synchronization

1. If the queue is empty, call notEmpty.await () method, the current thread is blocked waiting for [consumer]

2. After the element into the team, calling notFull.signal () method, Wake blocked [producer] thread

// Returns the element head of the queue
 // if the queue is empty, waiting until the queue is not empty 
public E Take () throws InterruptedException {
     Final of ReentrantLock = Lock the this .lock;
   // get the lock 
    lock.lockInterruptibly ();
     the try {
     / / If the queue is empty, waiting until the queue is not empty 
        the while (COUNT == 0 ) 
            notEmpty.await (); 
    // queue is not empty, return the head elements 
        return dequeue (); 
    } the finally {
     // release lock 
        lock.unlock (); 
    } 
} 
 
Private E dequeue () {
     //lock.getHoldCount Assert () ==. 1;
     // Assert items [takeIndex] = null;!
   // return the head elements 
    Final Object [] items = the this .items; 
    @SuppressWarnings ( "an unchecked" ) 
    E X = (E) items [takeIndex]; 
    items [takeIndex] = null ;
     IF (++ takeIndex == items.length) 
        takeIndex = 0 ; 
    COUNT - ;
     IF (the ITRS =! null ) 
        itrs.elementDequeued (); 
  // wake-up blocked notFull threads on 
    notFull.signal ();
    return x;
} 

Guess you like

Origin www.cnblogs.com/yeyang/p/12580584.html