Java concurrency-using built-in conditional queues for a simple bounded cache

Source: Internet
Author: User

Built-in lock and built-in condition queue together, a simple application is to create a blocking bounded buffer, Java and the blockingqueue of the contract is a blocking bounded queue implemented with lock and explicit conditional queue. Summarize the principles of built-in locks and built-in conditions, where we can implement a simple, blocking cache in another way. The source code is as follows:

First, create an abstract bounded cache class Aboundedbuffer, which provides a basic implementation of insertions and deletions.

/** * @title: Aboundedbuffer * @description: Bounded Cache abstract class * @update: 2014-12-30 9:29 : * @author: 172.17.5.73 * @version: 1.0.0 * @since: 2014-12-30 */public abstract class Aboundedbuffer< ; v> {private final v[] buf;private int tail;private int head;private int count;protected aboundedbuffer (int capacity) {th Is.buf = (v[]) new object[capacity];} Protected synchronized final void DoPut (v V) {Buf[tail] = v;if (++tail==buf.length) {tail = 0;} ++count;} Protected synchronized Final V Dotake () {v v = buf[head];buf[head] = null;if (++head==buf.length) {head = 0;} --count;return v;} Public Synchronized Final Boolean isfull () {return count = = buf.length;} Public Synchronized Final Boolean isEmpty () {return count==0;}} 

           second, using the built-in conditional queue, you write subclasses to implement blocking insertions and deletions. The insert operation, dependent on the condition that the cache is not full when the condition is not satisfied, calls the wait method to suspend the thread, once the insert succeeds, the cache is non-empty, then the call notifyall method wakes up waiting for a non-empty thread. The delete operation, dependent on the condition is non-null, when the condition is not satisfied, the same suspend wait, once the deletion succeeds, the cache is not full, evoking waiting for the condition of the thread. The simple source code is as follows:

Import java.util.date;/** * * @title: Innerconditionqueue * @description: Use built-in conditional queue to implement a simple bounded cache * through the object's W AIT and notify to implement the Suspend * Lock object is this, the object that calls Wait/notify is the same object. * Ternary relationship (lock, wait/notify, conditional predicate) * Defect: * When a thread is awakened from wait, the code condition predicate is not true and the condition needs to be judged at this point. So you have to call wait in the loop * each time you wake up to judge the true or false predicate. * Predicate: A description or description of the object (what it is, how, what to do), a term describing the nature, relationship, characteristics, etc. of the object.  * @update: 2014-12-18 pm 4:18:06 * @author: 172.17.5.73 * @version: 1.0.0 * @since: 2014-12-18 */public Class Innerconditionqueue<v> extends Aboundedbuffer<v> {protected innerconditionqueue (int capacity) { Super (capacity);} Public synchronized void put (V V) throws Interruptedexception{while (Isfull ()) {System.out.println (new Date () + ' buffer is ' Full thread Wait: "+thread.currentthread (). GetName ()); Wait ();} DoPut (v); Notifyall ();} Public synchronized V take () throws Interruptedexception{while (IsEmpty ()) {System.out.println (new Date () + ' buffer is ' Empty thread wait: "+tHread.currentthread (). GetName ()); Wait ();} V v = dotake ();//Whenever you wait for a condition, be sure to send a notification in some way when the conditional verb becomes true notifyall (); System.out.println (New Date () + "" "+thread.currentthread (). GetName () +" Take: "+v); return v;}

       Finally, write the test code, create a buffer of size 2, start three threads to perform the insert operation, and when the third thread executes, it hangs because the cache is full and the main thread deletes two records. Wait for the thread to be woken up successfully for insertion. When the cache is empty, subsequent deletions will be blocked until a new record is inserted. The test code is as follows:

Import Java.util.date;public class Main {public static void Main (string[] args) {final innerconditionqueue<string> Bu = new innerconditionqueue<string> (2); Thread t1 = new Thread (new Runnable () {@Overridepublic void run () {try {bu.put ("Hello1");} catch (Interruptedexception exec ption) {System.out.println ("INTERCETP1:" +thread.currentthread (). GetName ());}}); Thread t2 = new Thread (new Runnable () {@Overridepublic void run () {try {bu.put ("Hello2");} catch (Interruptedexception exec ption) {System.out.println ("INTERCETP2:" +thread.currentthread (). GetName ());}}); Thread t3 = new Thread (new Runnable () {@Overridepublic void run () {try {bu.put ("Hello3"); Thread.Sleep (50000); Bu.put ("Last one ..."); catch (Interruptedexception execption) {System.out.println ("INTERCETP3:" +thread.currentthread (). GetName ());}}); T1.start (); T2.start (); T3.start (); try {thread.sleep (); Bu.take (); Bu.take (); Bu.take (); Bu.take ();} catch ( Interruptedexception execption) {execption.printstacktrace ();} System.out.println (new Date () + "main over ...");}} 

Execution result: The first put operation of T3 is blocked because the cache is full, and after 5 seconds the main thread deletes two operations and wakes up again. The fourth bu.take () operation of the main thread is blocked because the cache is empty until T3 is awakened after 50 seconds after inserting "last one" and the operation ends.

Tue Dec 10:23:53 CST buffer is full thread wait:thread-2tue Dec 10:23:58 CST main take:hello1tue Dec 30 10 : 23:58 CST, main take:hello2tue Dec 10:23:58 CST, buffer is empty thread wait:maintue Dec 10:23:58 CST 2014 Main Take:hello3tue Dec 10:23:58 CST buffer is empty thread Wait:maintue Dec 10:24:48 CST main take:last o Ne ... Tue Dec 10:24:48 CST main over ...

Conclusion: The subclass of Blockingqueue Arrayblockingqueue is a blocking queue that is implemented with Reentrantlock and objectcondition, and the reason that the implementation chooses an explicit lock and an explicit conditional queue is that it is clear that The queued and outbound operations of this queue depend on two conditions, while reentrantlock can correlate multiple conditional queues. It's ingenious compared to our built-in queue for object: The thread waits in its waiting condition queue. In our case, both of these conditions are associated with the same conditional queue, and when a thread wakes up because another thread called notifyall, it does not mean that the condition it waits for is already true, which is the limitation of the built-in conditional queue.

Java concurrency-using built-in conditional queues for a simple bounded cache

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.