在Java程式語言即將年滿20歲的此刻(Java在1995/5/23正式發佈),讓我們來認識一下從JDK 7 U40版本開始正式加入的成員:Java Mission Control,簡稱:JMC。
這個工具程式是JDK內建的GUI工具,可以即時觀察到JVM中個應用程式的執行狀況。要啟動這個工具很簡單,只要開發環境安裝的是JDK 7 U40以上的版本,就可以從[檔案總管]找到在[JDK HOME]/bin中的jmc程式,直接雙擊就可以啟動該應用程式(Mac作業系統會自行開啟終端機,用指令啟動)並看到如下的畫面:
現在我們就用這個工具來觀察以前在JVM中無法偵測的DeadLock!
以下為一段一定會發生DeadLock的程式:
package jmc.test;
import java.util.Random;
public class LoadAndDeadLock {
public static void main(String[] args) {
Locker lock1 = new Locker("lock1");
Locker lock2 = new Locker("lock2");
LockerThread first = new
LockerThread("first", lock1, lock2);
LockerThread second = new LockerThread("second", lock2, lock1);
first.start();
second.start();
}
}
class LockerThread extends Thread {
private Locker locker1, locker2;
public LockerThread(String name, Locker l1, Locker l2) {
super(name);
locker1 = l1;
locker2 = l2;
}
public void run() {
int sleeptime;
loop:
while (true) {
synchronized (locker1) {
System.out.printf("執行緒[%s]已synchronized物件[%s]%n",
Thread.currentThread().getName(), locker1);
try {
sleeptime = new Random().nextInt(1000);
Thread.sleep(sleeptime);
} catch (InterruptedException ex) {}
synchronized (locker2) {
System.out.printf("執行緒[%s]已synchronized物件[%s]%n",
Thread.currentThread().getName(), locker2);
try {
sleeptime = new Random().nextInt(1000);
Thread.sleep(sleeptime);
} catch (InterruptedException ex) {}
locker1.index++;
locker2.index++;
System.out.printf("[%s] 完成: %d, %d\n",
Thread.currentThread().getName(), locker1.index, locker2.index);
}
System.out.printf("執行緒[%s]已結束synchronized物件[%s]的%n",
Thread.currentThread().getName(), locker2);
if (locker1.index >= 5) {
break loop;
}
}
System.out.printf("執行緒[%s]已結束synchronized物件[%s]%n%n",
Thread.currentThread().getName(), locker1);
}
}
}
class Locker {
int index;
String name;
Locker(
String n) {name = n;
}
public String toString() {
return super.toString() + ", " + name;
}
}
從Netbeans執行這支程式就會從[Output]視窗看到程式只產生兩行輸出,就因為DeadLock而停滯不前:
過去程式人員僅能從程式中去尋找是否可能發生了DeadLock,現在從JMC就可以立刻發現真兇!(程式請保持繼續執行,才能觀察喔!)
先從已啟動的JMC關閉「Welcome」畫面,即可從執行中的程式清單看到這個測試程式,展開該程式項目並點擊[MBean Server],出現右邊的監控畫面時,選擇[Threads]頁籤,就可以看到:
這裏清楚的看到城市中建立的兩個執行緒:first, second的狀態為BLOCKED,且Deadlocked狀態為:Yes! |