剛把手頭上的項目代碼擼完,閒來看看博客,而後就看到了線程這塊的東西。以前有簡單的記錄過線程和進行的零碎知識。
JAVA基礎知識系列---進程、線程安全安全
看着看着就想着怎麼能寫一個死鎖呢,打開eclipse,忽然感受無從下手;以前都是一直在解決阻塞、死鎖這些問題,如今反過來去寫一個死鎖感受有點莫名奇妙。。。bash
ok,寫一個死鎖就要有一種場景,而且知足死鎖的條件。app
首先要有競爭的資源,而且兩個線程要同時都在等待對方釋放資源。那咱們先弄兩個資源:eclipse
Object lock=new Object();
Object lock2=new Object();
複製代碼
而後有兩個線程:ide
Tr1 tr1=new Tr1(lock, lock2);
Tr2 tr2=new Tr2(lock, lock2);
Thread t1=new Thread(tr1);
Thread t2=new Thread(tr2);
複製代碼
啓動:post
t1.start();
t2.start();
複製代碼
那麼對於lock,lock2怎麼再線程內部產生競爭關係呢?來看代碼:this
package com.glmapper.base.synchronize;
public class Tr1 implements Runnable {
Object lock;
Object lock2;
public Tr1(Object lock,Object lock2){
this.lock= lock;
this.lock2= lock2;
}
@Override
public void run() {
//獲取lock
synchronized (lock) {
System.out.println(Thread.currentThread().getName()+"獲取了lock鎖");
try {
Thread.sleep(3000);
} catch (Exception e) {
}
//獲取lock2
synchronized (lock2) {
System.out.println(Thread.currentThread().getName()+"獲取了lock2鎖");
}
}
}
}
public class Tr2 implements Runnable {
Object lock;
Object lock2;
public Tr2(Object lock,Object lock2){
this.lock= lock;
this.lock2= lock2;
}
@Override
public void run() {
//獲取lock2
synchronized (lock2) {
System.out.println(Thread.currentThread().getName()+"獲取了lock2鎖");
try {
Thread.sleep(3000);
} catch (Exception e) {
}
//獲取lock
synchronized (lock) {
System.out.println(Thread.currentThread().getName()+"獲取了lock鎖");
}
}
}
}
複製代碼
分析一下:當線程1獲取lock時,線程2獲取了lock2鎖;而後線程1繼續執行,到這裏,spa
synchronized (lock2) {
System.out.println(Thread.currentThread().getName()+"獲取了lock2鎖");
}
複製代碼
此時須要獲取到lock2這個鎖,可是lock2如今被線程2持有;同時,線程2也開始執行到:線程
synchronized (lock) {
System.out.println(Thread.currentThread().getName()+"獲取了lock鎖");
}
複製代碼
此時線程2也在嘗試獲取lock這把鎖,可是lock又被線程1持有了。兩個線程都在等待對方釋放資源,形成了死鎖。OK,完成了。。。
當我準備關機時,發現還在等呢? code