Java High concurrency Programming: Thread Lock technology __ algorithm

Source: Internet
Author: User
Notes Summary

This article introduces the thread lock technology in JAVA5: Lock and condition, realizes the communication between threads, in which the use of read lock and write lock is demonstrated by a caching system, and the application of condition is demonstrated by a blocking queue.

Thread Lock Technology: Lock & Condition Implementation thread synchronization communication owning package: Java.util.concurrent.locks

Thread Lock Description
Synchronized Synchronization method, the lock object is this; synchronization static method, the lock object is byte code. Class; Sync code block, lock object is any object, but must be the same object
Lock Sync Lock Interface
Reentrantlock Lock (), Unlock (), newcondition ()
Readwritelock Read-Write Lock interface
Reentrantreadwritelock Readlock () Gets the read lock, Writelock () gets the write lock
Condition Inter-thread communication await () waiting for signal () wakeup
1. Lock

Lock is more object-oriented than the synchronized in the traditional threading model, and it has a broader locking operation than the Synchronized method and statement, which allows for a more flexible structure, can have very different properties, and can support multiple related Condition objects.

Similarly in real life, the lock itself is also an object. Code snippets executed by two threads to implement the result of a synchronization mutex, they must use the same lock object, which is in the internal method of the class that represents the resource being manipulated, not in the thread code. Reentrantlock

Method Declaration function Description
Lock () Get lock
Trylock () Attempt to acquire lock
Unock () Release lock
Newcondition () Get the condition of the lock

Common forms are as follows

Lock lock = new Reentrantlock ();

public void Dosth () {
    lock.lock ();
    try {
        //Perform certain operations
    }finally {
        lock.unlock ();
    }
}
Read and write lock

Divided into read lock and write lock, multiple read lock is not mutually exclusive, read lock and write lock mutually exclusive, write lock and write lock mutually exclusive, this is controlled by the JVM itself. You just have to do the proper lock. If your code reads only data, many people can read at the same time, but not at the same time, then read the lock; If your code modifies the data, only one person is writing and cannot read at the same time, then write the lock. In short, read the lock when reading, write the lock when writing.

Read and Write lock usage scenario: If the code reads data only, many people can read it together, but not at the same time. If the code modifies the data, only one person is writing and cannot read the data at the same time.

An example of a read-write lock cache provided by the Reentrantreadwritelock class in the API:

Class Cacheddata {  

Object data;  
    Volatile Boolean cachevalid;  

Reentrantreadwritelock rwl = new Reentrantreadwritelock ();  

void Processcacheddata () {      rwl.readlock (). Lock ();      if (!cachevalid) {      //must release read lock before acquiring write lock      rwl.readlock (). Unlock (); c12/>      Rwl.writelock (). Lock ();     Recheck state because another thread might have 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 ();      Rwl.writelock (). Unlock (); Unlock write, still hold read    } use       (data);      Rwl.readlock (). Unlock ();  

}  
}                                 

Read and Write lock application: Write a caching system

Note: In order to avoid thread security problems, synchronized and readwritelock can be, synchronized also prevent concurrent read, low performance there is a thread advanced to start reading data, to judge, found no data, other threads do not need to go in , the release of Read lock, plus write lock, to find data writing, in order to avoid writing to other objects to wait, and then make a judgment, data write, release the write lock, read the lock, to prevent writing, restore the original state.

Two judgements: The first time to write data, so release the read lock, write the lock. Second time to prevent blocked threads from repeatedly writing

Import Java.util.HashMap;  
Import Java.util.Map;  
Import Java.util.concurrent.locks.ReadWriteLock;  

Import Java.util.concurrent.locks.ReentrantReadWriteLock; public class Cachedemo {//define a MAP for caching objects private map<string, object> cache = new Hashmap<string, OBJ  

    Ect> ();  

    Gets a read-write lock object private Readwritelock RWL = new Reentrantreadwritelock ();      The method with the cached fetch of the specified value is public Object getData (String key) {Rwl.readlock (). Lock ();  
        Upper read lock Object value = null;  

                try{value = Cache.get (key);//Get the value if (= = = null) to query where security issues occur    Rwl.readlock (). Unlock (); No data, free read lock, write lock//multiple threads to write lock, first successful after the other thread blocked, the first thread began to execute the following code, the last//release write lock, the subsequent thread continues to write lock, in order to avoid the following thread
                Repeat write, two times to Judge Rwl.writelock (). Lock (); try{if (value==null) {//two-time judgment, prevent other threads from repeating the data value = "AAAA";//actually query the data  
   Library                 }}finally{Rwl.writelock (). Unlock ();  Write the data, release the Write Lock} rwl.readlock (). Lock ();    Restore read lock}}finally{rwl.readlock (). Unlock ();   Final release read lock} return value;   Returns the obtained value}}

False wake-up: Using a while instead of if

Lock lock = new Reentrantlock ();
try {
    lock.lock ();
    Need to lock code
}finally {
    lock.unlock ();
}

Read and write lock test

public class Readwritelocktest {public static void main (string[] args) {final Queue3 q3 = new Queue3 (); for (int i=0;i<3;i++) {new Thread () {public void run () {WH
                    Ile (True) {q3.get ();
            }}.start (); New Thread () {public void run () {while (true) {q3.put (new Rando
                    M (). Nextint (10000));
        }}.start ();
Class queue3{private Object data = null;
    Readwritelock rwl = new Reentrantreadwritelock ();
        public void Get () {Rwl.readlock (). Lock ();
            try {System.out.println (Thread.CurrentThread (). GetName () + "be ready to read data!");
            Thread.Sleep ((Long) (Math.random () *1000));
     System.out.println (Thread.CurrentThread (). GetName () + "have read data:" + data);   catch (Interruptedexception e) {e.printstacktrace ();
        }finally{rwl.readlock (). Unlock ();
        } public void put (Object data) {Rwl.writelock (). Lock ();
            try {System.out.println (Thread.CurrentThread (). GetName () + "be ready to write data!");
            Thread.Sleep ((Long) (Math.random () *1000));
            This.data = data;
        System.out.println (Thread.CurrentThread (). GetName () + "have write data:" + data);
        catch (Interruptedexception e) {e.printstacktrace ();
        }finally{rwl.writelock (). Unlock (); }
    }
}
Thread-0 be ready to read data!
Thread-2 be ready to read data!
Thread-4 be ready to read data!
Thread-0have Read Data:null
thread-2have read data:null
thread-4have read Data:null
Thread-5 be ready to WR Ite data!
Thread-5 have write data:7975
Thread-5 is ready to write data!
Thread-5 have write data:9832
Thread-3 is ready to write data!
Thread-3 have write data:2813
Thread-3 is ready to write data!
Thread-3 have write data:7998
Thread-1 is ready to write data!
Thread-1 have write data:6737
Thread-1 is ready to write data!
...
2. Condition

Used to implement communication between threads to solve problems that object.wait (), Nitify (), Notifyall () are difficult to use

Condition the object Monitor method (wait, notify, and Notifyall) into distinct objects to provide multiple waiting sets (Wait-set) for each object by using them in combination with any Lock implementation. Where Lock replaces the use of synchronized methods and statements, Condition replaces the use of the Object monitor method wait and notify

A lock can have more than one condition, that is, multiple waiting for the notification, the traditional threading mechanism in a monitor object can only wait and notify all the way, in order to implement multiple wait and notification, you must be nested use multiple synchronization monitor objects. Using a monitor often results in a trade-off.

When waiting for Condition, a "false wake-up" is allowed, often as a concession to the underlying platform semantics. For most applications, this has little practical impact because Condition should always be waiting in a loop and testing the status declaration being waited on. An implementation can remove possible false wakes at will, but it is recommended that application programmers always assume that these false wakes may occur and therefore always wait in a loop.

Method Declaration function Description
Await () Thread wait
Await (long, timeunit unit) The thread waits for a specific time, exceeding the wait time timeout
Signal () Randomly wakes up a waiting thread
Signalall () Wake Up all waiting threads

Condition applications: Blocking queues (using two monitors)

Description: This application is the sample code in the condition interface in the Java.util.concurrent.locks package. Using two condition to manage the data-fetching thread, and the thread that stored the data, so that you can explicitly wake up the desired class of threads, and if you use a condition, when the queue is full, the awakened one is not necessarily the thread that takes the data.

Class Boundedbuffer {final lock lock = new Reentrantlock ();   
  Final Condition notfull = Lock.newcondition ();   

  Final Condition notempty = Lock.newcondition ();  
  Final object[] items = new OBJECT[100];  

  int Putptr, takeptr, Count;  
    public void put (Object x) throws Interruptedexception {Lock.lock ();    try {while (count = = items.length)//loop to determine whether the queue is full notfull.await ();   
      If the queue is full, the thread to which the data is stored waits for items[putptr] = x;      if (++putptr = = items.length) Putptr = 0;//when the queue is full, the pointer returns to the 0 ++count;    Added a data notempty.signal ();  
    There is data in the queue, so the thread that wakes the data is finally {lock.unlock ();  
    } public Object take () throws Interruptedexception {Lock.lock ();   The try {while (count = = 0)//loop determines whether the queue has an empty notempty.await ();   
      The thread to fetch waits for Object x = items[takeptr];  
      if (++takeptr = = items.length) takeptr = 0;  --count; Take one, indicating that the queue has an idle position, notfull.signal (); //So notify the stored thread return x;  
    finally {Lock.unlock ();   }  
  }   
}

Condition test

public class Conditioncommunication {public static void main (string[] args) {final Business Business = new B
        Usiness ();
                        New Thread (New Runnable () {@Override public void run () {
                        for (int i=1;i<=5;i++) {business.sub (i);

        }}). Start ();
        for (int i=1;i<=5;i++) {business.main (i);
        } class Business {lock lock = new Reentrantlock ();
        Condition Condition = Lock.newcondition ();
        Private Boolean bshouldsub = true;
            public void Sub (int i) {lock.lock ();
                    try{while (!bshouldsub) {try {condition.await ();
                    catch (Exception e) {e.printstacktrace ();
             }
                }   for (int j=1;j<=2;j++) {System.out.println ("Sub thread sequence of" + j + ", loop of" + i);
                } bshouldsub = false;
            Condition.signal ();
            }finally{Lock.unlock ();
            }} public void main (int i) {lock.lock ();
                    try{while (bshouldsub) {try {condition.await ();
                    catch (Exception e) {e.printstacktrace ();  for (int j=1;j<=4;j++) {System.out.println ("main thread sequence of
                "+ j +", loop of "+ i";
                } bshouldsub = true;
            Condition.signal ();
            }finally{Lock.unlock (); }
        }
    }
}

Output Results

Sub thread sequence of 1,loop of 1 sub thread sequence of 2,loop of 1 main thread sequence of 1,loop of 1 main thread sequ Ence of 2,loop of 1 main thread sequence of 3,loop of 1 main thread sequence of 4,loop of 1 sub thread sequence of 1,loop of 2 sub thread sequence of 2,loop of 2 main thread sequence of 1,loop of 2 main thread sequence of 2,loop of 2 main threa D sequence of 3,loop of 2 main thread sequence of 4,loop of 2 sub thread sequence of 1,loop of 3 sub thread sequence of 2,  Loop of 3 main thread sequence of 1,loop of 3 main thread sequence of 2,loop of 3 main thread sequence of 3,loop of 3 main  Thread sequence of 4,loop of 3 sub thread sequence of 1,loop of 4 sub thread sequence of 2,loop of 4 main thread sequence of 1,loop of 4 main thread sequence of 2,loop of 4 main thread sequence of 3,loop of 4 main thread sequence of 4,loop of 4 Sub thread sequence of 1,loop of 5 sub thread sequence of 2,loop of 5 main thread sequence of 1,loop of 5 main thread SE Quence of 2,loop of 5 maIn thread sequence of 3,loop of 5 main thread sequence of 4,loop of 5 

The

implements a simple blocking queue myarrayblockingqueue using reentrantlock and condition, and if there is no data in the collection when the Take method is invoked, the calling thread blocks; If the put method is invoked, the collection data is full. Then it can also cause the calling thread to block. However, these two blocking conditions are different, respectively, for Notfull and Notempty

Import java.util.concurrent.locks.Condition;
Import Java.util.concurrent.locks.Lock;

Import Java.util.concurrent.locks.ReentrantLock;
    public class Myarrayblockingqueue<t> {//Data array private final t[] items;
    Lock private Final lock lock = new Reentrantlock ();
    Team full conditions private Condition Notfull = Lock.newcondition ();
    Team empty conditions private Condition Notempty = Lock.newcondition ();
    Header index private int head;
    Tail index private int tail;

    Number of data private int count;
    Public myarrayblockingqueue (int maxSize) {items = (t[]) new object[maxsize];
    Public Myarrayblockingqueue () {this (10);
        public void put (T-t) {lock.lock ();
                try {while (count = = getcapacity ()) {System.out.println ("Data is full, wait");
            Notfull.await ();
            } Items[tail] = t;
            if (++tail = = Getcapacity ()) {tail = 0;
           } ++count; Notempty.signalall (); Wake up the line waiting for data
Related Article

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.