效能監測的利器:Java Mission Control

作   者:戴玉佩 精誠資訊 恆逸教育訓練中心 資深講師
技術分類:程式設計

在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!

Share |
您可在下列課程中了解更多Java SE 7最新的程式開發技巧喔...
相關學習資源︰

【SL-275-SE7】Java SE7程式語言設計