Reentrantreadwritelock use of read/write Locks 2

Source: Internet
Author: User

This article can be used as a learning note for the Zhang Xiaoxiang-java multi-threading and concurrency Library advanced application.

In this section we do a caching system.


Before reading the festival
Please read first
Reentrantreadwritelock use of read/write locks 1

First edition
public class Cachedemo {    private map<string, object> cache = new hashmap<string, object> ();    public static void Main (string[] args) {        Cachedemo cd = new Cachedemo ();        SYSTEM.OUT.PRINTLN ("SS   " +cd.getdata2 ("ss"));        SYSTEM.OUT.PRINTLN ("SS   " +cd.getdata2 ("ss"));        System.out.println ("MM" +cd.getdata2 ("MM"   ));        System.out.println ("MM"   +cd.getdata2 ("mm"));    }    Public Object getData2 (String key) {        object O=cache.get (key);        if (o==null) {        //logo 1            System.out.println ("first check  not" +key);            O=math.random ();     Actually get            cache.put (Key, O) from the database;        }        return o;    }}
Operation Result:
First Check no SS
SS 0.4045014284225158
SS 0.4045014284225158
First Check no mm
MM 0.9994663041529088
MM 0.9994663041529088

There seems to be no problem.
What do you think?
If there are three threads at the same time for the first time to the identity of GetData2 () 1 (the key you are looking for is the same), check o is null, and then go to the database. In this case, it is equal to three lines Cheng Cha the same key, and then all went to the database.
This is obviously unreasonable.

The simplest way to synchronized the second edition
Public synchronized Object getData2 (String key) {
//.....

}


The third edition of the lock section we mentioned that Reentrantlock can replace synchronized, which is a more object-oriented design. Let's try it.
    Private Lock l=new Reentrantlock (); L as member variable of Cachedemo public    Object getData3 (String key) {        l.lock ();        Object O=null;        try {            o = cache.get (key);            if (o = = null) {//ID 1                System.out.println ("first check  no" + key);                o = Math.random (); Actually get                cache.put (Key, O) from the database,            }        } finally {            l.unlock ();        }        return o;    }
Can I have the third edition?
Can be a p.

Why, think for yourself.


We have to use Reentrantreadwritelock, which has both a read lock and a write lock in the same method.

First, I have another question:

For the same thread, can you add a read lock and then write the lock before unlocking the read lock?

In other words, does the following code stop?

public class Cachedemo {    private map<string, object> cache = new hashmap<string, object> ();    Private Readwritelock RWL = new Reentrantreadwritelock ();    public static void Main (string[] args) {        Cachedemo cd = new Cachedemo ();        Cd.getdata2 ();    }            public void GetData2 () {        rwl.readlock (). Lock ();        SYSTEM.OUT.PRINTLN (1);        Rwl.writelock (). Lock ();        SYSTEM.OUT.PRINTLN (2);        Rwl.readlock (). Unlock ();        SYSTEM.OUT.PRINTLN (3);        Rwl.writelock (). Unlock ();        SYSTEM.OUT.PRINTLN (4);}    }
Try it yourself, the console output 1, the program will not move.

the read lock must be unlocked before the write lock is added.

The fourth edition is a read lock and a write lock
public static void Main (string[] args) {Cachedemo cd = new Cachedemo ();        SYSTEM.OUT.PRINTLN ("ss" +cd.getdata4 ("ss"));                SYSTEM.OUT.PRINTLN ("ss" +cd.getdata4 ("ss"));        System.out.println ("MM" +cd.getdata4 ("mm"));    System.out.println ("MM" +cd.getdata4 ("mm"));        Public Object getData4 (String key) {Rwl.readlock (). Lock ();        Object O=null;            try {o=cache.get (key);                if (o==null) {System.out.println ("first check not" +key);  Rwl.readlock (). Unlock ();                   Identification 4 Rwl.writelock (). Lock ();                       try {if (value==null) {//id 0 value = "AAAA";//Actual call to Querydb ();                    Cache.put (Key,value);                  }} finally {Rwl.writelock (). Unlock (); } rwl.readlock (). Lock ();  ID 1}}finally {Rwl.readlock (). Unlock (); Callout 2        } return o;                  }
Results
First Check no SS
SS 0.5989899889645358
SS 0.5989899889645358
First Check no mm
MM 0.8534424949014686

MM 0.8534424949014686

There are three more questions about this one.

1 Why you have to unlock at Mark 2.
This answer has been mentioned in the previous section.

2 Why is there a lock on the ID 1?
If the identity 1 is not locked, and the program has been performing normally, then to the identity 2, it unlocked whose lock?


3 Why do I have to check the ID 0 out?
If at the same time three threads run to identity 4 (looking for the same key), one obtains a write lock, writes the data, and releases the write lock. At this time another two threads still need to go to the database to run a trip?

In addition, the identification 1 of the reading lock, put in the front of finally called the downgrade lock. I'm not quite sure about the downgrade lock at the moment.
An example of a downgrade lock is given in the official documentation, as follows
Class Cacheddata {   Object data;   Volatile Boolean cachevalid;   Final Reentrantreadwritelock rwl = new Reentrantreadwritelock ();   void Processcacheddata () {     rwl.readlock (). Lock ();     if (!cachevalid) {        //must release read lock before acquiring write lock        rwl.readlock (). Unlock ();        Rwl.writelock (). Lock ();        try {          //recheck state because another thread might has          //acquired write lock and changed state before we did.          if (!cachevalid) {            data = ...            Cachevalid = true;          }          Downgrade by acquiring read lock before releasing write lock          Rwl.readlock (). Lock ();        } finally {          Rwl.wri Telock (). Unlock (); Unlock write, still hold read        }     }     try {use       data;     } finally {       rwl.readlock (). Unlock ( );     }   } }

Thanks GLT




Reentrantreadwritelock use of read/write Locks 2

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.