1、原始構成:
synchronized是關鍵字,屬於JVM層面,底層是由一對monitorenter和monitorexit指令實現的。
ReentrantLock是一個具體類,是API層面的鎖。
2、使用方法:
synchronized不需要用戶手動釋放鎖,當synchronized代碼塊執行完成后,系統會自動讓線程釋放對鎖的占用
ReentrantLock需要用戶手動釋放鎖,若沒有手動釋放可能導致死鎖現象。
3、等待是否可中斷:
synchronized不可中斷,除非拋出異常或者正常運行完成
ReentrantLock可中斷
4、加鎖是否公平:
synchronized非公平鎖
ReentrantLock兩者都可以,默認是非公平鎖。
5、鎖綁定多個條件Condition:
synchronized沒有。
ReentrantLock可用來分組喚醒需要喚醒的線程。而不是像synchronized要么隨機喚醒一個線程,要么喚醒所有線程。
題目:多線程之間按順序調用,實現A->B->C三個線程啟動,要求如下:
* AA打印5次,BB打印10次,CC打印15次
* 緊接着
* AA打印5次,BB打印10次,CC打印15次
* 來10輪
class ShareResource {
private int number = 1;
private Lock lock = new ReentrantLock();
private Condition condition1 = lock.newCondition();
private Condition condition2 = lock.newCondition();
private Condition condition3 = lock.newCondition();
public void print5() {
lock.lock();
try {
while (number != 1) {
condition1.await();
}
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
number = 2;
condition2.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print10() {
lock.lock();
try {
while (number != 2) {
condition2.await();
}
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
number = 3;
condition3.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print15() {
lock.lock();
try {
while (number != 3) {
condition3.await();
}
for (int i = 1; i <= 15; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
number = 1;
condition1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class SyncAndReentrantLockDemo {
public static void main(String[] args) {
ShareResource shareResource = new ShareResource();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
shareResource.print5();
}
}, "AAA").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
shareResource.print10();
}
}, "BBB").start();
new Thread(() -> {
for (int i = 0; i < 10; i++) {
shareResource.print15();
}
}, "CCC").start();
}
}
