What's the difference between Synchronized and Lock?

The difference between synchronized and Lock:

Lock is an interface, and Synchronized is the key word.

2:Synchronized releases the lock automatically, and Lock must release the lock manually.

3:Lock can interrupt the response of the thread waiting for the lock, but Synchronized will not, and the thread will wait all the time.

4: Lock lets you know if a thread has a lock, but Synchronized can't.

5:Lock can improve the efficiency of multiple threads.

6:Synchronized locks classes, methods, and code blocks, while Lock is block-wide

 

  /**
* Synchronized: This control is added to objects that need to be synchronized. Synchronized can be added to methods or to specific code blocks, with brackets indicating objects that need to be locked.
* lock: You need to display the specified start and end locations. The ReentrantLock class is commonly used as a lock, and one ReentrantLock class must be used in multiple threads.
* As an object, the lock can be guaranteed to work.
* lock() and unlock() should be displayed at the locks and unlocks. So unlock() is typically written in the final block to prevent deadlocks.
  *
* synchronized originally used the CPU pessimistic lock mechanism, that is, the thread acquired the exclusive lock. Exclusive locks mean that other threads can only rely on blocking to wait for the thread to release the lock.
* When there are many threads competing for locks, it will cause frequent context switching of CPU, resulting in low efficiency.
* Lock uses optimistic locking. The so-called optimistic lock is to complete an operation on the assumption that there is no conflict without locking each time.
* If the conflict fails, try again until it succeeds.
* The mechanism of optimistic lock implementation is CAS operation (Compare and Swap). We can further study the source code of ReentrantLock,
* One of the more important ways to get locks is compareAndSetState. This is actually a special instruction provided by the CPU being invoked.
  */

Let's look at a small example of specific code:

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 ReentrantLock();
    /*
* Only after using the release can other threads acquire locks
     */
    public void lockTest(Thread thread) {
 
lock.lock(); // Acquire locks
        try {
System.out.println("thread"+thread.getName() +"get the current lock"); and //print the name of the current lock
Thread.sleep(2000); // To see the effect of execution, the thread hibernates here for 2 seconds
        } catch (Exception e) {
System.out.println("threads"+thread.getName()+ "abnormal release lock occurred");
        }finally {
System.out.println("threads"+thread.getName()+ "Executing the completed release lock");
lock.unlock(); // unlock
        }
    }
     
    public static void main(String[] args) {
 
        LockTest lockTest = new LockTest();
// Declare a thread "thread one"
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                lockTest.lockTest(Thread.currentThread());
            }
        }, "thread1");
// Declare a thread "Thread 2"
        Thread thread2 = new Thread(new Runnable() {
 
            @Override
            public void run() {
                lockTest.lockTest(Thread.currentThread());
            }
        }, "thread2");
// Start two threads
        thread2.start();
        thread1.start();
 
    }
}

Implementation results:

 

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 ReentrantLock();
    
    /*
     * tryLock() is an attempt to acquire a lock. If it succeeds, it returns true and false if the acquisition fails (that is, the lock has been acquired by other threads).
     */
    public void tryLockTest(Thread thread) {
if(lock.tryLock()) { //Attempt to acquire locks try { System.out.println("thread"+thread.getName() + "Get the current lock"); //Print the name of the current lock Thread.sleep(2000);//To see the effect of execution, the thread hibernates here for 2 seconds } catch (Exception e) { System.out.println("thread"+thread.getName() + "An abnormal release lock occurred"); }finally { System.out.println("thread"+thread.getName() + "Executed release lock"); lock.unlock(); //Release lock } }else{ System.out.println("I am thread."+Thread.currentThread().getName()+"The current lock is occupied by others and I can't get it."); } } public static void main(String[] args) {
LockTest lockTest = new LockTest();  //Declare a thread "thread one" Thread thread1 = new Thread(new Runnable() { @Override public void run() { lockTest.tryLockTest(Thread.currentThread()); } }, "thread1"); //Declare a thread "Thread 2" Thread thread2 = new Thread(new Runnable() { @Override public void run() { lockTest.tryLockTest(Thread.currentThread()); } }, "thread2"); // Start two threads thread2.start(); thread1.start(); } }

Implementation results:

 

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 ReentrantLock();
public void tryLockParamTest(Thread thread) throws InterruptedException {
if(lock.tryLock(3000, TimeUnit.MILLISECONDS)) { //Attempt to acquire a lock that cannot be acquired, wait 3 seconds, and return false if it is not acquired after 3 seconds try { System.out.println("thread"+thread.getName() + "Get the current lock"); //Print the name of the current lock Thread.sleep(4000);//To see the effect of execution, the thread hibernates here for 2 seconds } catch (Exception e) { System.out.println("thread"+thread.getName() + "An abnormal release lock occurred"); }finally { System.out.println("thread"+thread.getName() + "Executed release lock"); lock.unlock(); //Release lock } }else{ System.out.println("I am thread."+Thread.currentThread().getName()+"The current lock is occupied by someone else,Wait 3 s Not yet available,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 "Thread 2" Thread thread2 = new Thread(new Runnable() { @Override public void run() { try { lockTest.tryLockParamTest(Thread.currentThread()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }, "thread2"); // Start two threads thread2.start(); thread1.start(); } }

Implementation results:

Because thread 1 is dormant for 4 seconds at this time, thread 2 waits for 3 seconds to give up the acquisition lock and the execution ends.

The results of changing Thread.sleep(4000) to Thread.sleep(2000) in the method are as follows:

Because Thread 1 is dormant for 2 seconds, Thread 2 waits for 3 seconds while Thread 1 releases the lock. Thread 2 gets the lock and Thread 2 can execute.

Keywords: Java

Added by turtleman8605 on Tue, 14 May 2019 16:46:33 +0300