1. 程式人生 > 程式設計 >Java 多執行緒Synchronized和Lock的區別

Java 多執行緒Synchronized和Lock的區別

引言

在多執行緒中,為了使執行緒安全,我們經常會使用synchronized和Lock進行程式碼同步和加鎖,但是具體兩者有什麼區別,什麼場景下適合用什麼可能還不大清楚,主要的區別大致如下:

區別

1、synchronized是java關鍵字,而Lock是java中的一個介面

2、synchronized會自動釋放鎖,而Lock必須手動釋放鎖

3、synchronized是不可中斷的,Lock可以中斷也可以不中斷

4、通過Lock可以知道執行緒有沒有拿到鎖,而synchronized不能

5、synchronized能鎖住方法和程式碼塊,而Lock只能鎖住程式碼塊

6、Lock可以使用讀鎖提高多執行緒讀效率

7、synchronized是非公平鎖,ReentranLock可以控制是否公平鎖

從Lock介面中我們可以看到主要有5個方法,這些方法的功能從註釋中可以看出:

lock():獲取鎖,如果鎖被暫用則一直等待
unlock():釋放鎖
tryLock(): 注意返回型別是boolean,如果獲取鎖的時候鎖被佔用就返回false,否則返回true
tryLock(long time,TimeUnit unit):比起tryLock()就是給了一個時間期限,保證等待引數時間
lockInterruptibly():用該鎖的獲得方式,如果執行緒在獲取鎖的階段進入了等待,那麼可以中斷此執行緒,先去做別的事   通過 以上的解釋,大致可以解釋在上個部分中“鎖型別(lockInterruptibly())”,“鎖狀態(tryLock())”等問題,還有就是前面子所獲取的過程我所寫的“大致就是可以嘗試獲得鎖,執行緒可以不會一直等待”用了“可以”的原因。

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();
  }

}

執行結果:

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()),"t2");
    t1.start();
    t2.start();
  }
}

執行結果:

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

看到這裡相信大家也都會使用如何使用Lock了吧,關於tryLock(long time,TimeUnit unit)和lockInterruptibly()不再贅述。前者主要存在一個等待時間,在測試程式碼中寫入一個等待時間,後者主要是等待中斷,會丟擲一箇中斷異常,常用度不高,喜歡探究可以自己深入研究。

以上就是Java 多執行緒Synchronized和Lock的區別的詳細內容,更多關於Java 多執行緒Synchronized和Lock的資料請關注我們其它相關文章!