One. Lock thread Synchronization implements mutex
Lock is more object-oriented than the synchronized approach in the traditional threading model, similar to a lock in life, where the lock itself is an object.
Two threads running a code fragment to achieve the effect of a synchronous mutual exclusion. They must use the same lock object. A lock is an internal method on the class that represents the resource to be manipulated.
Instead of the thread code.
public class Locktest {public static void main (string[] args) {new locktest (). init ();} private void Init () {final Outputer outputer = new Outputer ();//thread 1new threads (new Runnable () {@Overridepublic void run () {while (true) {try {Thread.Sleep]; Outputer.output ("1111111111");} catch (Exception e) {e.printstacktrace ();}}}). Start ();//thread 2new thread (new Runnable () {@Overridepublic void run () {while (true) {try {Thread.Sleep]; outputer.output ("2222222222");} catch (Exception e) {e.printstacktrace ();}}}}). Start ();} Class Outputer {private lock lock = new Reentrantlock ();p ublic void output (String name) {lock.lock ();//Locking try {for (int i = 0; I < name.length (); i++) {System.out.print (Name.charat (i));} System.out.println ();} finally {lock.unlock ();//Release Lock}}}}
Two. read-write locks enable thread synchronization to repel each other
Read lock and write lock are divided into reading and writing locks. Multiple read locks are not mutually exclusive, read and write locks are mutually exclusive, and write and write locks are mutually exclusive. This is controlled by the JVM itself, and we just need to have the corresponding lock.
Suppose your code reads only the data and can be read by very many people at the same time. But can't write at the same time, then read the lock; Assuming your code changes the data, only one person can write. and cannot be read at the same time. Then write the lock. in short: Read the time to read the lock, write the time to write the lock
/** * Read-write lock case */public class Readwritelocktest {public static void main (string[] args) {final Queues Queues = new Queues (); Open 3 Read threads and 3 write threads for (int i = 0; i < 3; i++) {new Thread () {public void run () {while (true) {queues.get (); The method that invokes the read Data}}}.start (); new Thread () {public void run () {while (true) {Queues.put (New Random (). Nextint (10000));//Call the party that writes the data Law}}}.start ();}}} Class Queues {private Object data = NULL;//shared data, only one thread can write data, but can have multiple threads reading data at the same time private readwritelock RWL = new Reentrantre Adwritelock ();//Read the method: Use the Read lock Readlock () public void Get () {Rwl.readlock (). Lock (); try {System.out.println ( Thread.CurrentThread (). GetName () + "Get ready to read data!"); Thread.Sleep ((Long) math.random () * 1000); System.out.println (Thread.CurrentThread (). GetName () + "has read data:" + data);} catch (Interruptedexception e) {e.printstacktrace ();} finally {Rwl.readlock (). Unlock ();}} Write method: Use write lock Writelock () public void put (Object data) {Rwl.writelock (). Lock (); try {System.out.println ( Thread.CurrentThread (). GetName () + "Get ready to write data. "); Thread.Sleep ((Long) math.random () * +); this.data = data; Change shared Data System.out.println (Thread.CurrentThread (). GetName () + "have write data:" + data);} catch (Interruptedexception e) {e.printstacktrace ();} finally {Rwl.writelock (). Unlock ();}}
Note: The code that releases the lock must be placed in the finally, preventing the resource from being freed when unpredictable exceptions occur.
Three. Typical application of read/write lock
/** * Simple implementation of the cache */public class Cachedemo {private map<string, object> cache = new hashmap<string, object> ( ); Private Readwritelock RWL = new Reentrantreadwritelock (); Public Object GetData (String key) {//the user reads the value data, then reads the lock Rwl.readlock (). Lock () after entering the program. Object value = null; try {value = Cache.get (key); if (value = = null) {//The Read value is empty then the read lock is released, the write lock is opened, and the value is ready to be assigned Rwl.readlock (). Unlock (); Rwl.writelock (). Lock (); try {//Open write lock is blank, value is assigned XXX if (value = = null) {Valu e = "xxx"; Should actually go to the database query Querydb () cache.put (key, value); }} finally {//after using the write lock, turn off Rwl.writelock (). Unlock (); }//After releasing the write lock, resume the read lock Rwl.readlock (). Lock (); }} finally {//the user has finished reading and freed the read lock Rwl.readlock (). Unlock (); } return value; } }
Question: Why should I release the read lock before writing the lock? Why do I have to read the lock again after I release the Write lock?
We can think of the object lock as a real latch. A door can only have a latch.
So the latch to be written to release the Read latch.
Four. Condition implement thread synchronous communication
The condition function is similar to the object.wait and object.notify features in traditional threading technology, where a lock can be tired of having multiple condition, that is, multiple waits and notifications.
There is only one wait and notification on a monitor object in a traditional threading mechanism, and multiple synchronization monitor objects must be used to implement multiple waits and notifications:
/** * Three condition communication scene */public class Threeconditioncommunication {public static void main (string[] args) {final business Business = new Business ();//thread 1new threads (new Runnable () {@Overridepublic void Run () {for (int i = 1; I <= 5; i++) {bu Siness.sub1 (i);}}). Start ();//thread 2new thread (new Runnable () {@Overridepublic void Run () {for (int i = 1; I <= 5; i++) {business.sub2 (i);}} }). Start ();//thread 3new threads (new Runnable () {@Overridepublic void Run () {for (int i = 1; I <= 5; i++) {business.sub3 (i); }}). Start ();} Static class Business {private int flag = 1; Lock lock = new Reentrantlock (); Condition condition1 = Lock.newcondition (); Condition condition2 = Lock.newcondition (); Condition Condition3 = lock.newcondition ();p ublic void sub1 (int i) {try {lock.lock (); while (flag! = 1) {condition1.await () ;} for (int j = 1; J <=; J + +) {System.out.println ("Sub1 thread sequence of" + j + ", loop of" + i);} Flag = 2;condition2.signal ();} catch (Exception e) {e.printstacktrace ();} finally {LocK.unlock ();}} public void Sub2 (int. i) {try {lock.lock (); while (flag! = 2) {condition2.await ();} for (int j = 1; J <=; J + +) {System.out.println ("Sub2 thread sequence of" + j + ", loop of" + i);} Flag = 3;condition3.signal ();} catch (Exception e) {e.printstacktrace ();} finally {Lock.unlock ();}} public void Sub3 (int. i) {try {lock.lock (); while (flag! = 3) {condition3.await ();} for (int j = 1; J <=; J + +) {System.out.println ("SUB3 thread sequence of" + j + ", loop of" + i);} Flag = 1;condition1.signal ();} catch (Exception e) {e.printstacktrace ();} finally {Lock.unlock ();}}}}
Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.
JDK5 What is the new Thread lock technology (two)