Interview tube: Tell me about the difference between Java multithreading Synchronized and Lock?

In multi-threading, in order to make thread safety, we often use synchronized and Lock for code synchronization and locking, but what is the specific difference between the two, and which scenarios are suitable for use may not be clear. The main differences are roughly as follows:

the difference

1. Synchronized is a java keyword, and Lock is an interface in java

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

3. Synchronized is uninterruptible, and Lock can be interrupted or uninterrupted

4. Through Lock, you can know whether the thread has got the lock, but synchronized cannot

5. Synchronized can lock methods and code blocks, while Lock can only lock code blocks

6. Lock can use the read lock to improve the efficiency of multi-threaded reading

7. Synchronized is a non-fair lock, ReentranLock can control whether it is a fair lock

From the Lock interface, we can see that there are mainly five methods. The functions of these methods can be seen from the comments:

  • lock(): Acquire the lock, if the lock is temporarily used, wait forever
  • unlock(): release the lock
  • tryLock(): Note that the return type is boolean, if the lock is occupied when the lock is acquired, it returns false, otherwise it returns true
  • tryLock(long time, TimeUnit unit): Compared with tryLock(), it gives a time limit to ensure the waiting time for the parameter
  • lockInterruptibly (): a way to get the lock, if the thread is waiting to acquire the lock to enter the stage, you can interrupt this thread, to do something else   
    by the above explanations, can generally be explained in the previous section, "Lock Type (lockInterruptibly())", "lock state (tryLock())" and other issues, as well as the process of acquiring in the previous sub. What I wrote is "roughly you can try to acquire the lock, and the thread can not wait forever." Yes, the reason.

lock():

public class LockTest {
  private Lock lock = new ReentrantLock();

  private void method(Thread thread) {
    lock.lock();
    try {
      System.out.println(thread.getName() + " has gotten the lock!");
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      System.out.println(thread.getName() + " has unlocked the lock!");
      lock.unlock();
    }
  }

  public static void main(String[] args) {
    final LockTest test = new LockTest();

    Thread t1 = new Thread(new Runnable() {
      @Override
      public void run() {
        test.method(Thread.currentThread());
      }
    }, "t1");
    Thread t2 = new Thread(new Runnable() {
      @Override
      public void run() {
        test.method(Thread.currentThread());
      }
    }, "t2");
    t1.start();
    t2.start();
  }

}

operation result:

t1 has gotten the lock!
t1 has unlocked the lock!
t2 has gotten the lock!
t2 has unlocked the lock!

tryLock():

public class LockTest {
  private Lock lock = new ReentrantLock();

  private void method(Thread thread) {

    if (lock.tryLock()) {
      lock.lock();
      try {
        System.out.println(thread.getName() + " has gotten the lock!");
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        System.out.println(thread.getName() + " has unlocked the lock!");
        lock.unlock();
      }
    } else {
      System.out.println("I'm "+thread.getName()+". Someone has gotten the lock!");
    }
  }

  public static void main(String[] args) {
    LockTest test = new LockTest();

    Thread t1 = new Thread(() -> test.method(Thread.currentThread()), "t1");
    Thread t2 = new Thread(new Runnable() {
      @Override
      public void run() {
        test.method(Thread.currentThread());
      }
    }, "t2");
    t1.start();
    t2.start();
  }
}

operation result:

t1 has gotten the lock!
t1 has unlocked the lock!
I'm t2. Someone has gotten the lock!

Seeing this, I believe everyone will also use how to use Lock. I won’t go into details about tryLock(long time, TimeUnit unit) and lockInterruptibly(). The former mainly has a waiting time, and a waiting time is written in the test code. The latter mainly waits for an interrupt and throws an interrupt exception, which is not frequently used. If you like to explore, you can study it yourself.

Some high-frequency interview questions collected in the latest 2020 (all organized into documents), there are many dry goods, including mysql, netty, spring, thread, spring cloud, jvm, source code, algorithm and other detailed explanations, as well as detailed learning plans, interviews Question sorting, etc. For those who need to obtain these contents, please add Q like: 11604713672

Guess you like

Origin blog.csdn.net/weixin_51495453/article/details/114749311