1 synchronize是jvm層面,底層是monitorenter和monitorexit實現的;lock是具體類,api層面的鎖
2 synchronize不需要手動釋放鎖,當鎖住的代碼塊兒執行完後就會自動釋放。lock則需要手動調用unlock釋放鎖
3 synchronize等待不可中斷,除非拋異常或者方法正常完成。
lock可中斷,設置超時方法tryLock(timeout, timeunit)或lockInterruptibly()放代碼塊,調用interrupt()中斷
4 synchronize只能加非公平鎖,lock可以加公平鎖也可以加非公平鎖
5 synchronize只能隨機喚醒一個線程要麼全部喚醒,lock可以精確喚醒。
實現功能:從線程1開始,按照線程1,線程2,線程3的順序每個線程輪流打印從1到5,總計打印10次
/**
* print方法
* @param j 第幾次大循環
* @param expectNum 執行的線程設置的標識
* @param expectCondition 正在執行的condition
* @param afterNum 下一個線程執行的標識
* @param afterCondition 下個執行的condition
* @throws InterruptedException
*/
private void print(int j, int expectNum, Condition expectCondition, int afterNum, Condition afterCondition) throws InterruptedException {
// 加鎖
reentrantLock.lock();
while (number != expectNum) {
// 當前線程設置的expectNum!=正在執行的number則進行讓步
expectCondition.await();
}
// 執行打印任務
for (int i = 0; i < 5; i ++) {
System.out.println(j + "->" + Thread.currentThread().getName() + "->" + i);
}
// 設置下一個執行標誌位
number = afterNum;
// 喚醒後一個線程
afterCondition.signal();
// 釋放資源
reentrantLock.unlock();
}
測試代碼
private volatile int number = 1;
private ReentrantLock reentrantLock = new ReentrantLock();
private Condition c1 = reentrantLock.newCondition();
private Condition c2 = reentrantLock.newCondition();
private Condition c3 = reentrantLock.newCondition();
@Test
public void multiConditionTest() throws InterruptedException {
// 三個線程,輪流執行print方法10次
new Thread(() -> {
for (int i = 0; i < 10; i ++) {
try {
print(i, 1, c1, 2, c2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "線程1").start();
new Thread(() -> {
for (int i = 0; i < 10; i ++) {
try {
print(i, 2, c2, 3, c3);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "線程2").start();
new Thread(() -> {
for (int i = 0; i < 10; i ++) {
try {
print(i, 3, c3, 1, c1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "線程3").start();
TimeUnit.MINUTES.sleep(1);
}
測試結果
0->線程1->0
0->線程1->1
0->線程1->2
0->線程1->3
0->線程1->4
0->線程2->0
0->線程2->1
0->線程2->2
0->線程2->3
0->線程2->4
0->線程3->0
0->線程3->1
0->線程3->2
0->線程3->3
0->線程3->4
1->線程1->0
1->線程1->1
1->線程1->2
1->線程1->3
1->線程1->4
1->線程2->0
1->線程2->1
1->線程2->2
1->線程2->3
1->線程2->4
1->線程3->0
1->線程3->1
1->線程3->2
1->線程3->3
1->線程3->4
2->線程1->0
2->線程1->1
2->線程1->2
2->線程1->3
2->線程1->4
2->線程2->0
2->線程2->1
2->線程2->2
2->線程2->3
2->線程2->4
2->線程3->0
2->線程3->1
2->線程3->2
2->線程3->3
2->線程3->4
……