Synchronized和Lock的區別

引言java

  在多線程中,爲了使線程安全,咱們常常會使用synchronized和Lock進行代碼同步和加鎖,可是具體二者有什麼區別,什麼場景下適合用什麼可能還不大清楚,主要的區別大體以下:安全

區別多線程

    一、synchronized是java關鍵字,而Lock是java中的一個接口ide

    二、synchronized會自動釋放鎖,而Lock必須手動釋放鎖測試

    三、synchronized是不可中斷的,Lock能夠中斷也能夠不中斷spa

   四、經過Lock能夠知道線程有沒有拿到鎖,而synchronized不能線程

    五、synchronized能鎖住方法和代碼塊,而Lock只能鎖住代碼塊code

    六、Lock能夠使用讀鎖提升多線程讀效率blog

    七、synchronized是非公平鎖,ReentranLock能夠控制是否公平鎖接口

 

從Lock接口中咱們能夠看到主要有5個方法,這些方法的功能從註釋中能夠看出:

1 lock():獲取鎖,若是鎖被暫用則一直等待 
2 unlock():釋放鎖 
3 tryLock(): 注意返回類型是boolean,若是獲取鎖的時候鎖被佔用就返回false,不然返回true
4 tryLock(long time, TimeUnit unit):比起tryLock()就是給了一個時間期限,保證等待參數時間 
5 lockInterruptibly():用該鎖的得到方式,若是線程在獲取鎖的階段進入了等待,那麼能夠中斷此線程,先去作別的事   經過 以上的解釋,大體能夠解釋在上個部分中「鎖類型(lockInterruptibly())」,「鎖狀態(tryLock())」等問題,還有就是前面子所獲取的過程我所寫的「大體就是能夠嘗試得到鎖,線程能夠不會一直等待」用了「能夠」的緣由。

lock():

 1 public class LockTest {
 2     private Lock lock = new ReentrantLock();
 3 
 4     private void method(Thread thread) {
 5         lock.lock();
 6         try {
 7             System.out.println(thread.getName() + " has gotten the lock!");
 8         } catch (Exception e) {
 9             e.printStackTrace();
10         } finally {
11             System.out.println(thread.getName() + " has unlocked the lock!");
12             lock.unlock();
13         }
14     }
15 
16     public static void main(String[] args) {
17         final LockTest test = new LockTest();
18 
19         Thread t1 = new Thread(new Runnable() {
20             @Override
21             public void run() {
22                 test.method(Thread.currentThread());
23             }
24         }, "t1");
25         Thread t2 = new Thread(new Runnable() {
26             @Override
27             public void run() {
28                 test.method(Thread.currentThread());
29             }
30         }, "t2");
31         t1.start();
32         t2.start();
33     }
34 
35 }

運行結果:

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

 

tryLock():

 1 public class LockTest {
 2     private Lock lock = new ReentrantLock();
 3 
 4     private void method(Thread thread) {
 5     
 6         if (lock.tryLock()) {
 7             lock.lock();
 8             try {
 9                 System.out.println(thread.getName() + " has gotten the lock!");
10             } catch (Exception e) {
11                 e.printStackTrace();
12             } finally {
13                 System.out.println(thread.getName() + " has unlocked the lock!");
14                 lock.unlock();
15             }
16         } else {
17             System.out.println("I'm "+thread.getName()+". Someone has gotten the lock!");
18         }
19     }
20 
21     public static void main(String[] args) {
22         LockTest test = new LockTest();
23 
24         Thread t1 = new Thread(() -> test.method(Thread.currentThread()), "t1");
25         Thread t2 = new Thread(new Runnable() {
26             @Override
27             public void run() {
28                 test.method(Thread.currentThread());
29             }
30         }, "t2");
31         t1.start();
32         t2.start();
33     }
34 }

運行結果:

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()再也不贅述。前者主要存在一個等待時間,在測試代碼中寫入一個等待時間,後者主要是等待中斷,會拋出一箇中斷異常,經常使用度不高,喜歡探究能夠本身深刻研究。

相關文章
相關標籤/搜索