The difference between synchronized and Lock: java foundation

The main difference

  1. The lock mechanism is different: synchronized java is built-in keywords, the JVM level is achieved, the surveillance system will lock release or not, lock the JDK implementation of the code, you need to manually release, released in the finally block. Non-blocking manner may be employed acquire the lock;

  2. Performance is not the same: the case of resource competition incentives, lock performance will be better than synchronize, in the case competition is not excited, synchronize better than lock performance, synchronize competition will be based on the lock, from biased locking -> Lightweight lock -> heavyweight lock escalation, and programming easier

  3. synchronized unable to determine whether to acquire the lock state, Lock can determine whether to acquire the lock;

  4. synchronized automatically releases the lock (a thread executing the synchronization code will release the lock; the lock release exception occurs during the execution of the thread b), to be hand Lock release lock (UNLOCK () method releases the lock), otherwise easily result in the finally thread deadlock;

  5. synchronized keyword two threads 1 and 2 threads, if the current thread to acquire the lock 1, thread 2 thread waiting. If blocked thread 1, thread 2 will wait forever, while Lock locks will not necessarily wait any longer, get less than if you try to lock up the thread can not wait is over;

  6. synchronized reentrant locks, can not be interrupted, unfair, and Lock reentrant lock can be determined, be fair (both available)

  7. Usage not the same: synchronize may be used in the code block, the method. lock can only be written in the code, it can not directly modify the method.

  8. Lock can bind multiple condition. For example, ReentrantLock to implement threads are grouped need to wake up wake up, you can wake precise, synchronized or random rather than a wake, or wake up the entire thread.

 

Discussed separately synchronized, Lock

一:synchronized

Plus synchronous format: 

  synchronized (requires an arbitrary object (lock)) {

         In the discharge operation code block of shared data;

  } 

synchromized defect

  synchronized is a keyword in java, that is built-in features java language.

If a synchronized block of code is modified, when a thread gets the corresponding lock, and execute the code block, other threads can only have been waiting, waiting to acquire the lock thread releases the lock, and here to obtain the lock thread releases the lock there will only be two case:

(1) to obtain the lock change over a thread of execution of code blocks, and then releases the lock thread occupies

(2) thread execution exception occurs, then JVM will automatically thread releases the lock.

Example 1:

  If the thread that acquires the lock due to IO wait, or for other reasons (such as call sleep method) is blocked, but it does not release the lock, other threads will wait only dryly, Imagine how this affects performance efficiency.

  So you need to have a mechanism to prevent the thread has been waiting indefinitely to wait any longer (for example, only wait for a certain time or be able to respond to the interrupt), you can do so by Lock.

Example 2:

  When there are multiple threads to read and write files, read and write operations may conflict phenomenon, the phenomenon of conflict write and write operations occur, but read and read operations do not conflict occur.

  But to achieve synchronization using the synchronized keyword, it would cause a problem: If multiple threads are just a read operation, when a thread is performing a read operation, other threads can only wait can not be read.

 

  Therefore we need a mechanism to enable multiple threads are only read, not conflict between threads, it can be done by Lock.

  In addition, there is a thread Lock can know without success to obtain a lock. This is synchronized can not be done.

  In general, that is to say Lock provides more features than synchronized.

 

Two: LOCK

First to note is that, by looking at the source code LOCK know, lock an Interface

Interface lock using each method: lock () , tryLock () , tryLock (Long Time, TimeUnit Unit) , lockInterruptibly in () is used to acquire a lock. unLock () method is used to release the lock. Four lock method of obtaining the difference between:

(1) Lock () the most common method used when a method is used to obtain a lock if the lock has been acquired by another thread, then wait.

          Since we mentioned earlier if Lock, must take the initiative to release the lock, and when an abnormality occurs, does not automatically release the lock. Therefore, in general, use the lock must {} catch {} block in the try, and the lock release operation is performed in the finally block to ensure that the lock must be released out, the owner deadlocks.

 (2) tryLock () method returns a value, he said to try to acquire the lock, if the acquisition succeeds, it returns true, if the acquisition fails (ie the lock has been acquired by another thread), false returns, said this In any case the method will return immediately. When not get the lock would not have been where waiting

(3) tryLock (Long Time, TimeUnit Unit) similar to the method and time tryLock () method, but the difference is that this method when the lock will not get to wait for a certain time, within the time limits, or if not get the lock, returns false. If you start to get a lock or get a lock in period of waiting, it returns true.

(. 4) lockInterruptibly () method is special, when acquiring lock zone by this method, if the threads waiting to acquire a lock, it is possible to thread the corresponding interrupt, i.e. an interrupt-pending thread. That is, when even the threads simultaneously by lock.lockinterruputibly () to get a lock when, if at this time to acquire the lock thread A, and thread B only wait, then the thread calls threadB.interrupt () method can interrupt thread B is waiting for the process.

Note: When a thread gets the lock, it will not be interrupted interrupt () method

So when acquiring a lock by lockinterruptibly () method, if you can not get to, only the case where waiting is appropriate interrupt

And with synchronized modified so that when the state of a thread is waiting for a lock, it can not be interrupted, and only wait forever.

 

ReentrantLock

  Directly lock interface, we need to implement a number of ways, not convenient, ReentrantLock is the only class that implements the Lock interface , and provides more ways ReentrantLock, ReentrantLock, meaning "reentrant lock."

  ReadWriteLock is an interface, in which it defines only two methods:

    Used to obtain a read lock , used to obtain a write lock . That is to separate read and write files, divided into two to allocate to the thread lock so that multiple threads can be read simultaneously. ReentrantReadWriteLock realized ReadWriteLock interface.

 

ReentrantReadWriteLock

  ReentrantReadWriteLock which provided many ways, but the main two methods: readlock () and writelock used to obtain read and write locks

note:

  Note, however, that if there is a thread already occupied read lock, other threads at this time if you want to apply for a write lock, the write lock thread application will wait to release the read lock.

  If there is a thread already occupied write lock, then other threads at this time if the application write lock or read lock, the application thread will wait to release the write lock.

 

LOCK option and SYNCHRONIZED

  (1) lock is an interface, and is synchronized java keywords, synchronized built-in language;

  (2) synchronized when an exception occurs, it will automatically release the thread owns the lock, it will not lead to a deadlock phenomenon; and lock when an exception occurs, if there is no initiative by the unlock () to release the lock, then it may cause a deadlock and, therefore, the use of lock (lock needs to be released when finally block);

  (3) lock lets wait for the lock thread in response to interrupts, but it's not synchronized, when using synchronized, waiting threads will wait forever, Nana the dog does not respond to interrupts

  (4) through the lock can know without success to obtain a lock, and synchronized it can not be done

  (5) lock the plurality of threads can improve the efficiency of read operations

  

  In terms of performance, if not fierce competition for resources, the performance of both is similar, and very fierce competition for resources is (given the large number of threads at the same time competition), then lock the performance is much better than synchronized. So, when appropriate, select a specific use.  

 

Some small examples:

Package com.cn.test.thread.lock; 
 
Import java.util.concurrent.locks.Lock;
 Import java.util.concurrent.locks.ReentrantLock; 
 
public  class LockTest {
     Private Lock Lock = new new of ReentrantLock ();
     / * 
     * using after the completion of the release of another thread can acquire the lock 
     * / 
    public  void LockTest (the thread the thread) { 
        Lock.lock (); // get lock 
        the try { 
            System.out.println ( "threads" + thread.getName () + "get the current lock "); // Print name of the lock 
            the Thread.sleep (2000); // for the implementation of the results seen, where the thread is dormant 2 seconds 
        } the catch(Exception E) { 
            System.out.println ( "thread" + thread.getName () + "abnormality occurs lock release" ); 
        } the finally { 
            System.out.println ( "thread" + thread.getName () + " lock release is finished " ); 
            lock.unlock (); // release lock 
        } 
    } 
     
    public  static  void main (String [] args) { 
        LockTest LockTest = new new LockTest ();
         // declare a thread" a thread " 
        the thread Thread1 = new new the Thread ( new new the Runnable () { 
            @Override 
            public  void RUN () {
                lockTest.lockTest (Thread.currentThread ()); 
            } 
        }, "Thread1" );
         // declare a thread "two thread" 
        the Thread Thread2 = new new the Thread ( new new the Runnable () { 
 
            @Override 
            public  void RUN () { 
                lockTest.lockTest (Thread.currentThread ()); 
            } 
        }, "Thread2" );
         // start two threads 
        thread2.start (); 
        thread1.start (); 
 
    } 
}

Results of the:

  

 

Package com.cn.test.thread.lock; 

Import java.util.concurrent.locks.Lock;
 Import java.util.concurrent.locks.ReentrantLock; 

public  class LockTest {
     Private Lock Lock = new new of ReentrantLock (); 
    
    / * 
     * Try to obtain a lock tryLock () which represents the attempt to acquire the lock, if the acquisition succeeds, it returns true, if the acquisition fails (ie, the lock has been acquired by another thread), it returns false 
     * / 
    public  void tryLockTest (the thread the thread) {
         IF (lock .tryLock ()) { // attempt to acquire locks 
            the try { 
                System.out.println ( "threads" + thread.getName () + "to get the current lock"); // Print the name of the lock 
                Thread.sleep (2000);// is seen that the implementation of the results, where the thread is dormant 2 seconds 
            } the catch (Exception E) { 
                System.out.println ( "thread" + thread.getName () + "abnormality occurs lock release" ); 
            } the finally { 
                System.out.println ( "threads" + thread.getName () + "to release the lock is finished" ); 
                lock.unlock (); // release the lock 
            } 
        } the else { 
            System.out.println ( "I am the thread" + Thread.currentThread () getName () + "current lock somebody else, I can not get." );
        } 
    } 
    Public  static  void main (String [] args) { 
        LockTest LockTest= new LockTest();
        
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                lockTest.tryLockTest(Thread.currentThread());
            }
        }, "thread1");
        //声明一个线程 “线程二”
        Thread thread2 = new Thread(new Runnable() {

            @Override
            public void run() {
                lockTest.tryLockTest(Thread.currentThread());
            }
        }, "thread2");
         // start two threads 
        thread2.start (); 
        thread1.start (); 


    } 
}

Results of the:

 

Package com.cn.test.thread.lock; 

Import java.util.concurrent.TimeUnit;
 Import java.util.concurrent.locks.Lock;
 Import java.util.concurrent.locks.ReentrantLock; 

public  class LockTest {
     Private Lock Lock = new new of ReentrantLock ();
     public  void tryLockParamTest (the Thread Thread) throws InterruptedException {
         IF (lock.tryLock (3000, TimeUnit.MILLISECONDS)) { // try to acquire locks not obtain locks, on the other three seconds, 3 seconds, or if the acquisition less than returns false   
            the try { 
                System.out.println ( "threads" + thread.getName () + "to get the current lock"); //Print name of the lock 
                the Thread.sleep (4000); // for the implementation of the results seen, where the thread is dormant 2 seconds 
            } the catch (Exception E) { 
                System.out.println ( "thread" + thread.getName () + "abnormality occurs lock release" ); 
            } the finally { 
                System.out.println ( "thread" + thread.getName () + "finished release locks" ); 
                lock.unlock (); // release lock 
            } 
        } the else { 
            System.out.println ( "I am the thread" + Thread.currentThread () getName () + " current lock somebody else, wait 3s still can not get, give up." );
        } 
    } 
    Public  static void main(String[] args) {
        LockTest lockTest = new LockTest();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    lockTest.tryLockParamTest(Thread.currentThread());
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }, "thread1");
        // declare a thread "two thread" 
        the Thread Thread2 = new new the Thread ( new new the Runnable () { 
            @Override 
            public  void RUN () {
                 the try { 
                    lockTest.tryLockParamTest (Thread.currentThread ()); 
                } the catch (InterruptedException E) {
                     // Auto-Generated Block the catch TODO 
                    e.printStackTrace (); 
                } 
            } 
        }, "Thread2" );
         // start two threads 
        thread2.start (); 
        thread1.start (); 
    } 
}

Results of the:

Because the thread 1 dormant for four seconds, thread 2 wait 3 seconds not get to give up to acquire the lock, and execution ends

The method Thread.sleep (4000) to Thread.sleep (2000) performed as follows:

Because the dormant thread 1 2 seconds, the waiting thread 2 thread 1 during 3 seconds release the lock case to the thread 2 acquires the lock, the thread 2 can be carried out

 

 

Title: between multithreaded call by looking order to achieve A-> B-> C three thread starts, the following requirements :

  5 AA printing, BB print 10, print the CC 15, the process is repeated 10 times.

class ShareResource{
    private int number = 1; // A:1, B:2, C:3
    private Lock lock = new ReentrantLock();
    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();
    private Condition conditionC = lock.newCondition();
    public void print5(){
        try {
            lock.lock();
            while (number != 1){
                conditionA.await();
            }

            for (int i = 1; i <= 5; i++){
                System.out.print("A");
            }
            System.out.println();
            number++;
            conditionB.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void print10(){
        try {
            lock.lock();
            while (number != 2){
                conditionB.await();
            }

            for (int i = 1; i <= 10; i++){
                System.out.print("B");
            }
            System.out.println();
            number++;
            conditionC.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void print15(){
        try {
            lock.lock();
            while (number != 3){
                conditionC.await();
            }

            for (int i = 1; i <= 15; i++){
                System.out.print("C");
            }
            System.out.println();
            number = 1;
            conditionA.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
public class SynchronizedLockDifference {

    public static void main(String[] args) {
        ShareResource shareResource = new ShareResource();
        new Thread(()->{
            for (int i = 1; i <= 10; i++){
                shareResource.print5();
            }
        }, "A").start();

        new Thread(()->{
            for (int i = 1; i <= 10; i++){
                shareResource.print10();
            }
        }, "B").start();

        new Thread(()->{
            for (int i = 1; i <= 10; i++){
                shareResource.print15();
            }
        }, "C").start();

    }
}

Output:

AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC

Process finished with exit code 0

 

Guess you like

Origin www.cnblogs.com/myseries/p/11824568.html