And the objects modified by synchronized can be accessed by only one thread at a time, the Readwritelock interface provides a finer-grained locking mechanism. Readwritelock maintains a pair of related locks, one for read-only operations and the other for write operations. as long as there is no writer, the read lock can be persisted by multiple reader threads at the same time, but the write lock is exclusive.
Here is the test code:
Import Org.junit.test;import Java.text.simpledateformat;import Java.util.date;import Java.util.concurrent.locks.lock;import Java.util.concurrent.locks.readwritelock;import Java.util.concurrent.locks.reentrantreadwritelock;public class Readwritelockdemo {@Test public void test1 () throws interruptedexception {Data data = new data (); Worker T1 = new Worker (data, true);//read data worker t2 = new Worker (data, true);//Read Data T1.start (); T1.join (); T2.start (); T2.join (); } @Test public void Test2 () throws interruptedexception {Data data = new data (); Worker T1 = new Worker (data, true);//read data worker t2 = new Worker (data, false);//Set Data T1.start (); T1.join (); Thread.Sleep (1000); T2.start (); T2.join (); } @Test public void Test3 () throws interruptedexception {Data data = new data (); The worker T1 = new Worker (data, false);//Set data worker t2 = new Worker (data, true);//Read Data T1.start (); T1.join (); Thread.Sleep (1000); T2.start (); T2.join (); } @Test public void Test4 () throws interruptedexception {Data data = new data (); Worker T1 = new Worker (data, false),//Setting the T2 = new Worker (data, false),//Setting the T1.start (); T1.join (); Thread.Sleep (1000); T2.start (); T2.join (); }}class Data {static SimpleDateFormat SDF = new SimpleDateFormat ("Yyyy-mm-dd HH:mm:ss. SSS "); Readwritelock lock = new Reentrantreadwritelock (); Lock read = Lock.readlock (); Lock write = Lock.writelock (); public void Set () {Write.lock (); System.out.println (Thread.CurrentThread (). Hashcode () + "Set:begin" + Sdf.format (new Date ())); try {thread.sleep (5000); } catch (Exception e) {} finally {System.out.println (Thread.CurrentThread (). Hashcode () + "Set:end" + Sdf.format (New Date ())); Write.unlOck (); }} public int get () {read.lock (); System.out.println (Thread.CurrentThread (). Hashcode () + "Get:begin" + Sdf.format (new Date ())); try {thread.sleep (5000); } catch (Exception e) {} finally {System.out.println (Thread.CurrentThread (). Hashcode () + "Get:end" + Sdf.format (new Date ())); Read.unlock (); } return 1; }}class Worker extends Thread {data data; Boolean read; Public Worker (data data, Boolean read) {this.data = data; This.read = read; public void Run () {if (read) {data.get (); } else{Data.set (); } }}
The Run test1 () output results in the following:
751872434 get:begin 2016-05-04 14:53:49.6121431398495 get:begin 2016-05-04 14:53:49.613751872434 get:end 2016-05-04 14: 53:54.6131431398495 Get:end 2016-05-04 14:53:54.613process finished with exit code 0
Results analysis: The time that two threads read the data is coincident, indicating that the read lock Readlock can have multiple threads holding simultaneously, after the read lock is executed, the data can also be read by other threads.
The Run test2 () output results in the following:
2034193582 get:begin 2016-05-04 15:03:41.9962034193582 get:end 2016-05-04 15:03:47.0011431398495 set:begin 2016-05-04 1 5:03:48.0051431398495 Set:end 2016-05-04 15:03:53.007process finished with exit code 0
Results analysis: The thread that writes the data is executed after the read data thread has finished executing, indicating that the read lock Readlock is exclusive to the write lock Writelock, while the read operation does not allow other threads to write.
The Run test3 () output results in the following:
751872434 set:begin 2016-05-04 15:11:11.406751872434 set:end 2016-05-04 15:11:16.4091402691771 get:begin 2016-05-04 15:11:17.4101402691771 Get:end 2016-05-04 15:11:22.413process finished with exit code 0
Results analysis: The thread that reads the data is executed after the write data thread executes, indicating that the write lock Writelock is exclusive to the read lock Readlock, while the write operation does not allow other threads to read the operation.
The Run test4 () output results in the following:
926219290 set:begin 2016-05-04 15:14:53.647926219290 set:end 2016-05-04 15:14:58.6502112602078 set:begin 2016-05-04 15:14:59.6542112602078 Set:end 2016-05-04 15:15:04.657process finished with exit code 0
Results analysis: The second thread that writes the data is executed after the first write data thread has finished executing, indicating that the write lock Writelock is mutually exclusive and the write operation does not allow other threads to write.
Summarize:
When using read-write lock Readwritelock, multiple read operations can be performed concurrently, but the write operation is exclusive to the data resource.
Extended:
In choosing a read-write lock Readwriteloc or a synchronous lock synchronized, we can weigh the two factors:
1. The frequency with which the data is read relative to the data being written;
2. Number of threads waiting to be executed after data is written to lock;
Generally, in a read-write operation that requires concurrency control, read-write locks can be considered to improve concurrency efficiency when reading data at a high frequency and not frequently writing data.
1.ReadWriteLock usage
2.jdk-api-doc/readwritelock.html
"Java" read-write lock Readwritelock interface