死鎖四個條件:
1.互斥條件:(一個資源只能被一個進程占用)
2.不可剝奪條件:(某個進程占有的資源头谜,只有這個進程能釋放)
3.循環(huán)條件:(多個進程之間 首尾相接的循環(huán)等待資源)
4.請求和保持條件:(進程會去請求資源,但是持有資源會保持不變鸠澈,不釋放)
上述的“進程”可以理解成“線程”
死鎖例子:
public class TestDeadLock{
Object wait1 = new Object();
Object wait2 = new Object();
private void test1(){
try{
synchronized(wait1){
System.out.println("join test1 start...");
Thread.sleep(1000);
synchronized(wait2){
System.out.println("test1 搶wait2鎖成功...");
}
System.out.println("join test1 end...");
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
private void test2(){
try{
synchronized(wait2){
System.out.println("join test2 start...");
Thread.sleep(1000);
synchronized(wait1){
System.out.println("test2 搶wait1鎖成功...");
}
System.out.println("join test2 end...");
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
LockLockTest lock = new LockLockTest();
new Thread(new Runnable(){
@Override
public void run(){
lock.test1();
}
}).start();
new Thread(new Runnable(){
@Override
public void run(){
lock.test2();
}
}).start();
}
}
打印結(jié)果:
join test1 start...
join test2 start...
解讀上述代碼:
1.synchronized 就是滿足死鎖條件----互斥條件----
2.test1方法占用wait1資源 (synchronized(wait1))和 test2方法占用wait2資 源(synchorized(wait2)---不可剝奪條件---
3.test1 保持資源wait1請求資源wait2
test2 保持資源wait2 請求資源wait1
---請求和保持條件---
synchorized(wait1){
...
syschorized(wait2){
...
}
...
}
和
synchorized(wait2){
...
syschorized(wait1){
...
}
...
}
4.synchorized同時有兩個進程爭奪柱告,就會升級為輕量級鎖截驮,也可以理解自旋鎖。
例如:wait1資源目前A線程持有际度。B線程獲取wait1資源葵袭,目前已被占有,只能CAS自旋等待資源乖菱。
---循環(huán)等待---