synchronized是關鍵字,屬於JVM層面,經過wait,notify和notifyAll來調度線程。java
Lock是具體類,是api層面的鎖。api
synchronized不須要用戶手動去釋放鎖, 當synchronized代碼執行完後,系統會自動釋放鎖。多線程
Lock須要用戶手動釋放鎖,不然會出現死鎖現象。須要lock和unlock配合try/finally語句塊來完成。spa
synchronized不可中斷,除非拋出異常或者正常運行完畢。線程
Lock可中斷,能夠設置超時方法或者調用中斷方法。code
synchronized非公平鎖。blog
Lock默認非公平鎖,可指定爲公平鎖。get
synchronized沒有。it
Lock用來分組喚醒須要喚醒的線程,能夠精確喚醒,而不是像synchronized同樣要麼隨機喚醒一個線程,要麼所有喚醒。io
Demo: 練習
多線程之間按順序調用,實現A->B->C三個線程啓動,要求:AA打印5次,BB打印10次,CC打印15次,重複10遍。
package com.demo.lock; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class ShareResource{ int number = 1; private Lock lock = new ReentrantLock(); private Condition c1 = lock.newCondition(); private Condition c2 = lock.newCondition(); private Condition c3 = lock.newCondition(); public void print5(){ lock.lock(); try { while(number!=1){ c1.await(); } for(int i=1;i<=5;i++){ System.out.println(Thread.currentThread().getName()+"\t"+i); } number = 2; c2.signal(); } catch (Exception e) { e.printStackTrace(); }finally{ lock.unlock(); } } public void print10(){ lock.lock(); try { while(number!=2){ c2.await(); } for(int i=1;i<=10;i++){ System.out.println(Thread.currentThread().getName()+"\t"+i); } number = 3; c3.signal(); } catch (Exception e) { e.printStackTrace(); }finally{ lock.unlock(); } } public void print15(){ lock.lock(); try { while(number!=3){ c3.await(); } for(int i=1;i<=15;i++){ System.out.println(Thread.currentThread().getName()+"\t"+i); } number = 1; c1.signal(); } catch (Exception e) { e.printStackTrace(); }finally{ lock.unlock(); } } } public class TestReentrantLock { public static void main(String[] args) { ShareResource shareResource = new ShareResource(); new Thread(()->{ for(int i=1;i<=10;i++){ shareResource.print5(); } },"AA").start(); new Thread(()->{ for(int i=1;i<=10;i++){ shareResource.print10(); } },"BB").start(); new Thread(()->{ for(int i=1;i<=10;i++){ shareResource.print15(); } },"CC").start(); } }