線程的生命週期分爲以下幾種情況
1:當創建一個線程的時候: New的狀態
2:執行start: 就緒狀態,這個時候還沒有運行,需要分配CPU的資源才能運行
3: 運行狀態: 該線程被調度了分配到了CPU資源
4:如果一切正常,線程裏的代碼執行完,銷燬狀態(Terminated);
4.1: 如果在運行時執行了wait()這個時候就進入了等待狀態,但是這個狀態即會釋放CPU執行權,如果有鎖也會釋放鎖
4.2: 如果在運行時執行了sleep(1000),進入等待超時狀態 這個狀態只會釋放CPU執行權,不會釋放鎖
4.3: 如果在運行時執行了yelid(), 或者CPU執行權被搶了,這個時候又會回到第二個狀態,就緒.
4.5: 如果線程處在4.2狀態,這個時候執行interrupt方法,這個時候就會進入到2的狀態也就是就緒狀態
4.5: 如果線程處在4.1狀態,這個時候執行notify或者notifyAll,線程會進入到2的狀態也就是就緒狀態
4.6:如果線程中需要獲取synchronized鎖,進入到阻塞狀態,獲取到了鎖進入到就緒狀態.
4.7:如果線程處在4.2狀態,等時間到,這個時候會進入到2的狀態也就是就緒狀態
Java發生死鎖的條件
1: 多個線程(Thread)操作多個資源(Resource) Thread要大於Resource 而且它們要>=2
2: 爭奪資源的順序不對.
3: 拿到了資源死不放手.
舉個例子
public static void diedLocd(){
Object one = new Object();
Object two = new Object();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (one){
System.out.println("get one");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (two){
System.out.println("get two");
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
synchronized (two){
System.out.println("get two");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (one){
System.out.println("get onw");
}
}
}
}).start();
}
上面這種情況肯定死鎖,
解決方法 :
1: 上面是爭奪資源順序不對,把第一個鎖都換成one 第二個變成two肯定不會
2: 上面死鎖是一直拿到鎖不釋放,我們可以採用Lock裏的tryLock方法,但是爲了避免活鎖,最好做一個小點的延時
代碼如下
public static void unDiedLocd() {
Lock one = new ReentrantLock();
Lock two = new ReentrantLock();
Random random = new Random();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
if (one.tryLock()) {
System.out.println("get one");
try {
if (two.tryLock()) {
try {
System.out.println("get two");
break;
} finally {
two.unlock();
}
}
} finally {
one.unlock();
}
}
try {
Thread.sleep(random.nextInt(3));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
if (two.tryLock()) {
System.out.println("get one");
try {
if (one.tryLock()) {
try {
System.out.println("get two");
break;
} finally {
one.unlock();
}
}
} finally {
two.unlock();
}
}
try {
Thread.sleep(random.nextInt(3));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}