The previously mentioned synchronized mutexes and Reentrantlock are exclusive locks that can only be accessed by one thread at a time. While read-write locks allow multiple read threads to be accessed at the same time, all read threads and all other write threads will block when there is a write thread. Read-write locks maintain a pair of locks, a read lock, and a write lock, which increases concurrency because reading threads are blocked when using exclusive locks, which in contrast does improve parallelism.
In addition to ensuring the visibility of the write operation and the degree of parallelism of the read operation, the read-write lock simplifies the programming scene of the read-write interaction. Just imagine that in a situation where you read more and write less, if there is no read-write lock, the normal interaction mechanism is the wait/notify mechanism, that is, at the beginning of the write operation, all the read operations later than the write operation will be in a blocking state, only when the write operation completes the operation and the notification, read operation can get the opportunity to execute. The use of read and write locks can greatly simplify the programming difficulty, in the read operation to obtain read locks, because read locks can be read by multiple threads to obtain, so improve the degree of parallelism, write operations to obtain write locks. Read and write to use and read more than write scenes, Java read-write lock important implementation is reentrantreadwritelock. The upper interface of the Reentrantreadwritelock is Readwritelock. The Readwritelock interface has only two methods: Readlock () and Writelock ().
Here is an example to illustrate the use of Reentrantreadwritelock: The code implements a caching example
Package com.rhwayfun.concurrency.r0405;
Import Java.text.DateFormat;
Import Java.text.SimpleDateFormat;
Import Java.util.Date;
Import Java.util.HashMap;
Import Java.util.Map;
Import Java.util.concurrent.TimeUnit;
Import Java.util.concurrent.locks.Lock;
Import Java.util.concurrent.locks.ReentrantReadWriteLock;
/** * Created by Rhwayfun on 16-4-5.
* * public class Cache {static map<string,object> Map = new hashmap<string, object> ();
static Reentrantreadwritelock RW = new Reentrantreadwritelock ();
static Lock Readlock = Rw.readlock ();
static Lock Writelock = Rw.writelock ();
static DateFormat format = new SimpleDateFormat ("HH:mm:ss");
/** * Gets a key corresponding to the value * @param key * @return/public static final Object get (String key) {
Readlock.lock ();
try {return map.get (key);
}finally {readlock.unlock (); }/** * Sets the value of the key and returns the old value * @param key *@param value */public static final Object put (String key,object value) {Writelock.lock ();
try {return map.put (key,value);
}finally {writelock.unlock ();
}/** * Empty all content * * public static final void clear () {writelock.lock ();
try {map.clear ();
}finally {writelock.unlock ();
}/** * Write thread/Static class Writer implements runnable{private cache cache;
Public Writer (cache cache) {This.cache = cache;
public void Run () {Long start = System.currenttimemillis ();
int i = 0; for (;;
i++) {if (System.currenttimemillis ()-Start > 1000 * 5) {break;
try {TimeUnit.SECONDS.sleep (2); The catch (Interruptedexception e) {e.Printstacktrace ();
String value = Format.format (new Date ());
Cache.put (String.valueof (i), value); System.out.println (Thread.CurrentThread (). GetName () + ": Is writing data" + string.valueof (i) + "=
"+ Value +" at "+ Format.format (new Date ()); } System.out.println (Thread.CurrentThread (). GetName () + ": Finish writing data at" + forma
T.format (New Date ());
}/** * Read thread/Static class Reader implements runnable{private cache cache;
Public Reader (cache cache) {This.cache = cache;
public void Run () {int i = 0; for (;;
i++) {Object obj = cache.get (string.valueof (i));
if (obj instanceof String) {System.out.println (Thread.CurrentThread (). GetName () + ": Is reading data" + string.valueof (i) + "=" + obj + "at" + Format.format (new Date ()); }}} public static void Main (string[] args) throws Interruptedexception {Cache
cache = new cache ();
New Thread (New Writer (cache), "Writer"). Start ();
TimeUnit.SECONDS.sleep (5);
for (int i = 0; i < 5; i++) {New Reader (cache), "reader" + i). Start ();
TimeUnit.SECONDS.sleep (1);
}
}
}
The results of the program running are as follows:
The cache combination in the above example uses a HashMap-safe as the implementation of caching, while using read and write locks to ensure that the cache is thread-safe. A read lock is used in the read operation get method so that concurrent access to the method is not blocked. Write locks are used in the write put method, the write lock must be acquired in advance when the HashMap is updated, and the thread that acquires the write lock will block the acquisition of Read and write locks, and the other read and write operations will continue to execute only after the write lock is freed.