實現一個方法計時器

系統中有很多地方需要統計一個方法執行完畢,所花費的時間。 

有的需求是在統計一個大任務時, 同時分段統計子任務所花費的時間。 

比較常見的統計比如統計servlet執行所花費的時間, 可以寫一個filter對servlet做攔截 。 對FilterChain的doFilter()方法計時。 


寫了一個TimerUtil的實現如下:

package timer;

import java.util.Stack;

/**
 * 計時工具類
 * 用於給程序中的方法計時,來跟蹤那些比較耗時的方法
 * 使用 ThreadLocal實現,可以安全的在多線程當中執行
 * 並支持子任務
 * @author zhoufeng
 */
public class TimerUtil {
	
	private static final ThreadLocal<Stack<TimerEntry>> timerEntry = new ThreadLocal<Stack<TimerEntry>>() ;
	
	/**
	 * 開始一個計時器
	 * @param name  
	 */
	public static void start(String name) {
		Stack<TimerEntry> timerEntries = timerEntry.get() ;
		if(timerEntries == null){
			timerEntries = new Stack<TimerEntry>();
			timerEntry.set(timerEntries) ;
		}
		
		TimerEntry entry = new TimerEntry() ;
		entry.name = name ;
		entry.startTiem = System.currentTimeMillis() ;
		entry.stopTime = -1 ;
		
		timerEntries.push(entry) ;

	}
	
	/**
	 * 結束當前的計時器
	 * @return返回當前計時器花費的時間(毫秒)
	 */
	public static long timing() {
		TimerEntry currentEntry = getCurrentTimerEntry();
		if(currentEntry != null){
			currentEntry.stopTime = System.currentTimeMillis() ;
			long timeConsuming = currentEntry.stopTime - currentEntry.startTiem ;
			timerEntry.get().pop(); 
			return timeConsuming ;
		}
		return -1;
	}
	
	/**
	 * 此方法應該在timing()方法之前調用 ,因爲timing()方法操作完之後,會將當前的計時任務pop出棧
	 * @return當前計時器的名字
	 */
	public static String getCurrentNameTimerName(){
		TimerEntry currentEntry = getCurrentTimerEntry();
		if(currentEntry != null){
			return currentEntry.name ;
		}
		return null ;
	}
	
	/**
	 * 清除計時器
	 */
	public static void clear(){
		timerEntry.set(null) ;		
	}
	

	private static TimerEntry getCurrentTimerEntry(){
		Stack<TimerEntry> timerEntries = timerEntry.get() ;
		if(timerEntries != null){
			return timerEntries.peek() ;
		}
		return null ;
	}

	
	private static class TimerEntry{
		public String name ;
		public long startTiem ;
		public long stopTime ;
	}

	
}


寫個測試類。 來分別統計m1()  m2() m3() 執行所花費的時間。 以及main方法執行完成花費的時間, 代碼如下:

package timer;

public class TimerTest {

	public static void m1(){
		try {
			Thread.sleep(1000) ;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Method1 done.");
	}

	public static void m2(){
		try {
			Thread.sleep(2000) ;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Method2 done.");
	}

	public static void m3(){
		try {
			Thread.sleep(3000) ;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Method3 done.");
	}

	public static void main(String[] args) {

		long timeConsume  ;
		long m1Cs  ;
		long m2Cs  ;
		long m3Cs  ;
		try{
			
			TimerUtil.start("total task");

			try{
				TimerUtil.start("m1()");
				m1() ;
			}finally{
				m1Cs = TimerUtil.timing(); 
			}
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			
			try{
				TimerUtil.start("m2()");
				m2() ;
			}finally{
				m2Cs = TimerUtil.timing(); 
			}
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			

			try{
				TimerUtil.start("m3()");
				m3() ;
			}finally{
				m3Cs = TimerUtil.timing(); 
			}
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			

		}finally{
			timeConsume = TimerUtil.timing() ;
		}
		
		TimerUtil.clear() ;
		
		System.out.println("m1Cs:" + m1Cs);
		System.out.println("m2Cs:" + m2Cs);
		System.out.println("m3Cs:" + m3Cs);
		System.out.println("totalConsume:" + timeConsume);


	}

}

打印結果:

Method1 done.
Method2 done.
Method3 done.
m1Cs:1000
m2Cs:2000
m3Cs:3000
totalConsume:9000



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章