閱讀974 返回首頁    go 阿裏雲 go 技術社區[雲棲]


《 Java並發編程從入門到精通》 Java線程池的監控

本文是《 Java並發編程從入門到精通》第9章 線程的監控及其日常工作中如何分析的9.1節 Java線程池的監控。

 

看不到不等於不存在!讓我們來看看工作中是如何找問題解決問題的。

鳥欲高飛先振翅,人求上進先讀書。

京東,亞馬遜,當當均有銷售。


9.1 Java線程池的監控

如果想實現線程池的監控,必須要自定義線程池繼承ThreadPoolExecutor類,並且實現beforeExecute,afterExecute和terminated方法,我們可以在任務執行前,執行後和線程池關閉前幹一些事情。如監控任務的平均執行時間,最大執行時間和最小執行時間等。這幾個方法在線程池裏是空方法。如:

//每執行一個工作任務線程之前都會執行此實現的方法

protected void beforeExecute(Thread t, Runnable r) {

//t – 放在線程池裏麵要執行的線程。
//r – 將要執行這個線程的線程池裏麵的工作線程。

}

 

//每執行一個工作任務線程之後都會執行的方法

protected void afterExecute(Runnable r, Throwable t) {

//r – 已經運行結束的工作線程。
//t – 運行異常。

}

 

//線程池關閉之前可以幹一些事情;

protected void terminated() { };

 

線程池裏有一些屬性在監控線程池的時候可以使用: 

  1. taskCount:線程池需要執行的任務數量。
  2. completedTaskCount:線程池在運行過程中已完成的任務數量。小於或等於taskCount。
  3. largestPoolSize:線程池曾經創建過的最大線程數量。通過這個數據可以知道線程池是否滿過。如等於線程池的最大大小,則表示線程池曾經滿了。
  4. getPoolSize:線程池的線程數量。如果線程池不銷毀的話,池裏的線程不會自動銷毀,所以這個大小隻增不+
  5. getActiveCount:獲取活動的線程數。

 

大家想一想如果你來寫的話如何去寫,提供實例demo如下,慢慢體會一下:

public class MonitorThreadPoolExecutorDemo {

public static void main(String[] args) throws InterruptedException, ExecutionException {

Thread. sleep(500L);// 方便測試

ExecutorService executor = new MonitorThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS , new LinkedBlockingQueue() );

for (int i = 0; i < 3; i++) {

Runnable runnable = new Runnable() {

public void run() {

try {

Thread. sleep(100L);

catch (InterruptedException e) {

e.printStackTrace();

}

}

};

executor.execute(runnable);

}

executor.shutdown();

System. out.println(“Thread Main End!” );

}

}

class MonitorThreadPoolExecutor extends ThreadPoolExecutor {

public MonitorThreadPoolExecutor(int arg0, int arg1, long arg2, TimeUnit arg3, BlockingQueue<Runnable> arg4) {

super(arg0, arg1, arg2, arg3, arg4);

}

protected void beforeExecute(Thread paramThread, Runnable paramRunnable) {

System. out.println(“work_task before:” + paramThread.getName());

}

protected void afterExecute(Runnable r, Throwable t) {

super.afterExecute(r, t);

System. out.println(“work_task after worker thread is :” + r);

}

protected void terminated() {

System. out.println(“terminated getCorePoolSize:” + this.getCorePoolSize() + “;getPoolSize:” + this.getPoolSize() + “;getTaskCount:” + this .getTaskCount() + “;getCompletedTaskCount:”

this.getCompletedTaskCount() + “;getLargestPoolSize:” + this.getLargestPoolSize() + “;getActiveCount:” + this.getActiveCount());

System. out.println(“ThreadPoolExecutor terminated:” );

}

}

運行結果如下:

work_task before:pool-1-thread-1

work_task before:pool-1-thread-3

work_task before:pool-1-thread-2

Thread Main End!

work_task after worker thread is :demo.thread.MonitorThreadPoolExecutorDemo$1@13bbe97

work_task after worker thread is :demo.thread.MonitorThreadPoolExecutorDemo$1@70125b

work_task after worker thread is :demo.thread.MonitorThreadPoolExecutorDemo$1@ceba90

terminated getCorePoolSize:5;getPoolSize:0;getTaskCount:3;getCompletedTaskCount:3;getLargestPoolSize:3;getActiveCount:0

ThreadPoolExecutor terminated:

 

最後更新:2017-05-22 13:32:12

  上一篇:go  Java Date Time 教程-java.util.Calendar和GregorianCalendar
  下一篇:go  《 Java並發編程從入門到精通》 常見的內存溢出的三種情況