001/* 002 * JKNIV, SQLegance keeping queries maintainable. 003 * 004 * Copyright (C) 2017, the original author or authors. 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software Foundation, Inc., 018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 019 */ 020package net.sf.jkniv.experimental; 021 022/** 023 * Multi-thread timer keeper. 024 * 025 * @author Alisson Gomes 026 * @since 0.6.0 027 * 028 */ 029public class TimerKeeper 030{ 031 private long startTimer; 032 private long milliseconds; 033 private long times; 034 private static final ThreadLocal<TimerKeeper> TIMERS = new ThreadLocal<TimerKeeper>(); 035 036 private TimerKeeper() 037 { 038 this.startTimer = System.currentTimeMillis(); 039 this.milliseconds = 0L; 040 this.times = 0; 041 } 042 043 public static boolean isRunning() 044 { 045 TimerKeeper timerKeeper = TIMERS.get(); 046 if (timerKeeper != null) 047 return timerKeeper.startTimer > 0L; 048 049 return false; 050 } 051 052 /** 053 * start the chronometer timer 054 * @return the started time in milliseconds sliced by pause times. 055 * After pause <code>startTimer</code> become to zero. 056 */ 057 public static long start() 058 { 059 TimerKeeper timerKeeper = TIMERS.get(); 060 if (timerKeeper == null) 061 { 062 timerKeeper = new TimerKeeper(); 063 TIMERS.set(timerKeeper); 064 timerKeeper.times++; 065 } 066 else if (timerKeeper.startTimer == 0) 067 { 068 timerKeeper.startTimer = System.currentTimeMillis(); 069 timerKeeper.times++; 070 } 071 // else if (timerKeeper.startTimer > 0) 072 // { 073 // timerKeeper.milliseconds += System.currentTimeMillis() - timerKeeper.startTimer; 074 // } 075 return timerKeeper.startTimer; 076 } 077 078 /** 079 * Pause the chronometer timer 080 * @return the slice from last start until this pause. To obtain the 081 * total time call {@link #time()} method. 082 */ 083 public static long pause() 084 { 085 TimerKeeper timerKeeper = TIMERS.get(); 086 long sliceTime = 0L; 087 if (timerKeeper == null) 088 throw new IllegalStateException("start time doesn't called"); 089 090 if (timerKeeper.startTimer > 0) 091 sliceTime = System.currentTimeMillis() - timerKeeper.startTimer; 092 093 timerKeeper.milliseconds += sliceTime; 094 timerKeeper.startTimer = 0; 095 return sliceTime; 096 } 097 098 public static long time() 099 { 100 TimerKeeper timerKeeper = TIMERS.get(); 101 if (timerKeeper == null) 102 return 0L; 103 104 return timerKeeper.milliseconds; 105 } 106 107 public static long avg() 108 { 109 TimerKeeper timerKeeper = TIMERS.get(); 110 if (timerKeeper == null) 111 return 0L; 112 113 return timerKeeper.milliseconds / timerKeeper.times; 114 } 115 116 /** 117 * remove the chronometer from thread-local 118 * @return the time in milliseconds from chronometer 119 */ 120 public static long clear() 121 { 122 TimerKeeper timerKeeper = TIMERS.get(); 123 if (timerKeeper == null) 124 return 0L; 125 126 TIMERS.remove(); 127 return timerKeeper.milliseconds; 128 } 129 130 public static long times() 131 { 132 TimerKeeper timerKeeper = TIMERS.get(); 133 if (timerKeeper == null) 134 return 0L; 135 136 return timerKeeper.times; 137 } 138}