2013-04-22 66 views
2

我正在開發一個項目,在該項目中,我嘗試對我的一些客戶端代碼進行基準測試。每20分鐘分析一次程序行爲

所以對於我寫了一個Multithreading program這將產生多個線程,每個線程將運行的時間特定的時間和程序完成後,我打電話logHistogramInfo() method在finally塊來打印出historgram information對我來說,這將告訴我的客戶端代碼的表現如何。

下面是我的代碼中,我產卵多線程和finally塊,我打電話了logHistogramInfo method -

public static void main(String[] args) { 

    try { 

     readPropertyFiles(args); 

     //create thread pool with given size 
     ExecutorService service = Executors.newFixedThreadPool(noOfThreads); 

     long startTime = System.currentTimeMillis(); 
     long endTime = startTime + (durationOfRun * 60 * 1000); 

     for (int i = 0; i < threads; i++) { 
      service.submit(new CassandraReadTask(endTime, columnFamilyList)); 
     } 

     service.shutdown(); 
     service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 
    } catch (InterruptedException e) { 

    } catch (Exception e) { 

    } finally { 
     logHistogramInfo(); 
    } 

    LOG.info("All threads are finished"); 
} 

下面是我的直方圖方法 -

private static void logHistogramInfo() { 

    int[] definition = { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 }; 
    long[] buckets = new long[definition.length]; 

    System.out.println("Milliseconds   Number"); 
    SortedSet<Long> keys = new TreeSet<Long>(CassandraTimer.histogram.keySet()); 
    for (long key : keys) { 
     Long value = CassandraTimer.histogram.get(key); 
     System.out.println(key + "      " + value); 
    } 

    //Histogram information 
    for (Long time : CassandraTimer.histogram.keySet()) { 
     for (int i = definition.length - 1; i >= 0; i--) { 
      if (time >= definition[i]) { 
       buckets[i] += CassandraTimer.histogram.get(time); 
       break; 
      } 
     } 
    } 
    for (int i = 0; i < definition.length; i++) { 
     String period = ""; 
     if (i == definition.length - 1) { 
      period = "greater than " + definition[i] + " ms"; 
     } else { 
      period = "between " + (definition[i] + 1) + " and " + definition[i + 1] + " ms"; 
     } 
     LOG.info(buckets[i] + " came back " + period); 
    } 
} 

問題陳述: -

Everthing對我來說工作正常。現在唯一的問題是,假設如果我正在運行我的程序,那麼我需要等待我的程序完成。只有10個小時後,我可以看到結果是什麼。

我有興趣在程序運行時看到結果。只是想知道該程序的行爲。我不想等10個小時,然後看到結果。

現在我想到的是,假設我正在我的計劃10 hours然後每隔10分鐘或20分鐘後(它應該是可配置的)應該調用logHistogramInfo() method並告訴我結果。

程序結束後,它會自動調用finally塊中的logHistogramInfo() method。所以我最終能夠獲得完整的圖像。但每隔20分鐘後,我就可以看到程序是如何運行的,而不是等待程序完成。這可能嗎?

任何示例都會有很大的幫助。

更新代碼: -

有了下面的代碼,它不是每隔幾分鐘後打印日誌。我嘗試過調試並將斷點放在try塊中,並且它也沒有觸及那個斷點。任何想法爲什麼?

// queue some tasks 
long startTime = System.currentTimeMillis(); 
long endTime = startTime + (durationOfRun * 60 * 1000); 

for (int i = 0; i < threads; i++) { 
     service.submit(new CassandraReadTask(endTime, columnFamilyList)); 
} 

service.shutdown(); 

loggingAfterEveryXMinutes(); 
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 


/** 
* This is a simple which will call the logHistogramInfo method after every X Minutes 
*/ 
private static void loggingAfterEveryXMilliseconds() { 
    new Thread() { 
     public void run() { 
      while (true) { 
       try { 
        Thread.sleep(loggingEveryXMilliseconds); 
       } 
       catch (InterruptedException ex) { 

       } 
       logHistogramInfo(); 
      } 
     } 
    }.start();  
} 

回答

1

你有兩個選擇:

1)預配置的「更新週期」

這是你已經確定瞭解決方案。它只是由建立額外的線程,像這樣,做記錄的:

new Thread() { 
    public void run() { 
     while (true) { 
      try { Thread.sleep(numMinutes * 60 * 1000); } 
      catch (InterruptedException ex) { } 
      logHistogramInfo(); 
     } 
    } 
}; 

2)請在直方圖信息可以按需檢索鉤

有幾種方法可以做到這一點,但最常見的是簡單地設置一個HTTP服務器,您可以從瀏覽器中點擊以呈現信息(或者,只要HTTP服務器被擊中,程序就可以將柱狀圖信息呈現爲日誌文件)

Apache Commons對於快速建立這種事情很有用,但它確實沒有太多:

new Thread() { 
    public void run() { 
     ServerSocker serverSocket = new ServerSocket(12345); 
     while (true) { 
      Socket socket = serverSocket.accept(); 
      PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()); 
      pw.println("Histogram Info"); 
      // Print histogram info 
      pw.flush(); pw.close(); 
      socket.close(); 
     } 
    } 
} 
+0

感謝建議的扭矩。我會和你相信的第一個選擇一起去。你能告訴我在哪裏我應該把這段代碼放在我的代碼中嗎?我不想把這件事搞砸,所以這就是我問的原因。謝謝您的幫助。 – ferhan 2013-04-22 01:13:18

+0

最好的地方可能是在調用'service.shutdown()' – torquestomp 2013-04-22 01:29:02

+0

之前,謝謝,還有一件事,第一個選項和第二個選項有什麼不同?我無法理解你的第二個選擇? – ferhan 2013-04-22 01:31:46