计时器StopWatch的几种写法

下面提供三种计时器的写法供大家参考,大家可以自行选择自己钟爱的使用。

 

写法一(Spring 包提供的计时器):

  1 import java.text.NumberFormat;
  2 import java.util.LinkedList;
  3 import java.util.List;
  4 
  5 /**
  6  * Simple stop watch, allowing for timing of a number of tasks,
  7  * exposing total running time and running time for each named task.
  8  *
  9  * <p>Conceals use of {@code System.currentTimeMillis()}, improving the
 10  * readability of application code and reducing the likelihood of calculation errors.
 11  *
 12  * <p>Note that this object is not designed to be thread-safe and does not
 13  * use synchronization.
 14  *
 15  * <p>This class is normally used to verify performance during proof-of-concepts
 16  * and in development, rather than as part of production applications.
 17  *
 18  * @author Rod Johnson
 19  * @author Juergen Hoeller
 20  * @author Sam Brannen
 21  * @since May 2, 2001
 22  */
 23 public class StopWatch {
 24 
 25     /**
 26      * Identifier of this stop watch.
 27      * Handy when we have output from multiple stop watches
 28      * and need to distinguish between them in log or console output.
 29      */
 30     private final String id;
 31 
 32     private boolean keepTaskList = true;
 33 
 34     private final List<TaskInfo> taskList = new LinkedList<TaskInfo>();
 35 
 36     /** Start time of the current task */
 37     private long startTimeMillis;
 38 
 39     /** Is the stop watch currently running? */
 40     private boolean running;
 41 
 42     /** Name of the current task */
 43     private String currentTaskName;
 44 
 45     private TaskInfo lastTaskInfo;
 46 
 47     private int taskCount;
 48 
 49     /** Total running time */
 50     private long totalTimeMillis;
 51 
 52 
 53     /**
 54      * Construct a new stop watch. Does not start any task.
 55      */
 56     public StopWatch() {
 57         this("");
 58     }
 59 
 60     /**
 61      * Construct a new stop watch with the given id.
 62      * Does not start any task.
 63      * @param id identifier for this stop watch.
 64      * Handy when we have output from multiple stop watches
 65      * and need to distinguish between them.
 66      */
 67     public StopWatch(String id) {
 68         this.id = id;
 69     }
 70 
 71 
 72     /**
 73      * Return the id of this stop watch, as specified on construction.
 74      * @return the id (empty String by default)
 75      * @since 4.2.2
 76      * @see #StopWatch(String)
 77      */
 78     public String getId() {
 79         return this.id;
 80     }
 81 
 82     /**
 83      * Determine whether the TaskInfo array is built over time. Set this to
 84      * "false" when using a StopWatch for millions of intervals, or the task
 85      * info structure will consume excessive memory. Default is "true".
 86      */
 87     public void setKeepTaskList(boolean keepTaskList) {
 88         this.keepTaskList = keepTaskList;
 89     }
 90 
 91 
 92     /**
 93      * Start an unnamed task. The results are undefined if {@link #stop()}
 94      * or timing methods are called without invoking this method.
 95      * @see #stop()
 96      */
 97     public void start() throws IllegalStateException {
 98         start("");
 99     }
100 
101     /**
102      * Start a named task. The results are undefined if {@link #stop()}
103      * or timing methods are called without invoking this method.
104      * @param taskName the name of the task to start
105      * @see #stop()
106      */
107     public void start(String taskName) throws IllegalStateException {
108         if (this.running) {
109             throw new IllegalStateException("Can't start StopWatch: it's already running");
110         }
111         this.running = true;
112         this.currentTaskName = taskName;
113         this.startTimeMillis = System.currentTimeMillis();
114     }
115 
116     /**
117      * Stop the current task. The results are undefined if timing
118      * methods are called without invoking at least one pair
119      * {@code start()} / {@code stop()} methods.
120      * @see #start()
121      */
122     public void stop() throws IllegalStateException {
123         if (!this.running) {
124             throw new IllegalStateException("Can't stop StopWatch: it's not running");
125         }
126         long lastTime = System.currentTimeMillis() - this.startTimeMillis;
127         this.totalTimeMillis += lastTime;
128         this.lastTaskInfo = new TaskInfo(this.currentTaskName, lastTime);
129         if (this.keepTaskList) {
130             this.taskList.add(lastTaskInfo);
131         }
132         ++this.taskCount;
133         this.running = false;
134         this.currentTaskName = null;
135     }
136 
137     /**
138      * Return whether the stop watch is currently running.
139      * @see #currentTaskName()
140      */
141     public boolean isRunning() {
142         return this.running;
143     }
144 
145     /**
146      * Return the name of the currently running task, if any.
147      * @since 4.2.2
148      * @see #isRunning()
149      */
150     public String currentTaskName() {
151         return this.currentTaskName;
152     }
153 
154 
155     /**
156      * Return the time taken by the last task.
157      */
158     public long getLastTaskTimeMillis() throws IllegalStateException {
159         if (this.lastTaskInfo == null) {
160             throw new IllegalStateException("No tasks run: can't get last task interval");
161         }
162         return this.lastTaskInfo.getTimeMillis();
163     }
164 
165     /**
166      * Return the name of the last task.
167      */
168     public String getLastTaskName() throws IllegalStateException {
169         if (this.lastTaskInfo == null) {
170             throw new IllegalStateException("No tasks run: can't get last task name");
171         }
172         return this.lastTaskInfo.getTaskName();
173     }
174 
175     /**
176      * Return the last task as a TaskInfo object.
177      */
178     public TaskInfo getLastTaskInfo() throws IllegalStateException {
179         if (this.lastTaskInfo == null) {
180             throw new IllegalStateException("No tasks run: can't get last task info");
181         }
182         return this.lastTaskInfo;
183     }
184 
185 
186     /**
187      * Return the total time in milliseconds for all tasks.
188      */
189     public long getTotalTimeMillis() {
190         return this.totalTimeMillis;
191     }
192 
193     /**
194      * Return the total time in seconds for all tasks.
195      */
196     public double getTotalTimeSeconds() {
197         return this.totalTimeMillis / 1000.0;
198     }
199 
200     /**
201      * Return the number of tasks timed.
202      */
203     public int getTaskCount() {
204         return this.taskCount;
205     }
206 
207     /**
208      * Return an array of the data for tasks performed.
209      */
210     public TaskInfo[] getTaskInfo() {
211         if (!this.keepTaskList) {
212             throw new UnsupportedOperationException("Task info is not being kept!");
213         }
214         return this.taskList.toArray(new TaskInfo[this.taskList.size()]);
215     }
216 
217 
218     /**
219      * Return a short description of the total running time.
220      */
221     public String shortSummary() {
222         return "StopWatch '" + getId() + "': running time (millis) = " + getTotalTimeMillis();
223     }
224 
225     /**
226      * Return a string with a table describing all tasks performed.
227      * For custom reporting, call getTaskInfo() and use the task info directly.
228      */
229     public String prettyPrint() {
230         StringBuilder sb = new StringBuilder(shortSummary());
231         sb.append('\n');
232         if (!this.keepTaskList) {
233             sb.append("No task info kept");
234         }
235         else {
236             sb.append("-----------------------------------------\n");
237             sb.append("ms     %     Task name\n");
238             sb.append("-----------------------------------------\n");
239             NumberFormat nf = NumberFormat.getNumberInstance();
240             nf.setMinimumIntegerDigits(5);
241             nf.setGroupingUsed(false);
242             NumberFormat pf = NumberFormat.getPercentInstance();
243             pf.setMinimumIntegerDigits(3);
244             pf.setGroupingUsed(false);
245             for (TaskInfo task : getTaskInfo()) {
246                 sb.append(nf.format(task.getTimeMillis())).append("  ");
247                 sb.append(pf.format(task.getTimeSeconds() / getTotalTimeSeconds())).append("  ");
248                 sb.append(task.getTaskName()).append("\n");
249             }
250         }
251         return sb.toString();
252     }
253 
254     /**
255      * Return an informative string describing all tasks performed
256      * For custom reporting, call {@code getTaskInfo()} and use the task info directly.
257      */
258     @Override
259     public String toString() {
260         StringBuilder sb = new StringBuilder(shortSummary());
261         if (this.keepTaskList) {
262             for (TaskInfo task : getTaskInfo()) {
263                 sb.append("; [").append(task.getTaskName()).append("] took ").append(task.getTimeMillis());
264                 long percent = Math.round((100.0 * task.getTimeSeconds()) / getTotalTimeSeconds());
265                 sb.append(" = ").append(percent).append("%");
266             }
267         }
268         else {
269             sb.append("; no task info kept");
270         }
271         return sb.toString();
272     }
273 
274 
275     /**
276      * Inner class to hold data about one task executed within the stop watch.
277      */
278     public static final class TaskInfo {
279 
280         private final String taskName;
281 
282         private final long timeMillis;
283 
284         TaskInfo(String taskName, long timeMillis) {
285             this.taskName = taskName;
286             this.timeMillis = timeMillis;
287         }
288 
289         /**
290          * Return the name of this task.
291          */
292         public String getTaskName() {
293             return this.taskName;
294         }
295 
296         /**
297          * Return the time in milliseconds this task took.
298          */
299         public long getTimeMillis() {
300             return this.timeMillis;
301         }
302 
303         /**
304          * Return the time in seconds this task took.
305          */
306         public double getTimeSeconds() {
307             return (this.timeMillis / 1000.0);
308         }
309     }
310 
311 }

 

下面写一个调用:

public static void main(String[] args) throws InterruptedException {
//        StopWatchTest.test0();
     StopWatchTest.test1();
}

public static void test1() throws InterruptedException {
     StopWatch sw = new StopWatch("test");
     sw.start("task1");
     // do something
    Thread.sleep(100);
    sw.stop();
    sw.start("task2");
    // do something
    Thread.sleep(200);
    sw.stop();
    System.out.println("sw.prettyPrint()~~~~~~~~~~~~~~~~~");
    System.out.println(sw.prettyPrint());
}
运行结果:
sw.prettyPrint()~~~~~~~~~~~~~~~~~
StopWatch 'test': running time (millis) = 308
-----------------------------------------
ms     %     Task name
-----------------------------------------
00104  034%  task1
00204  066%  task2
--------------------- 

  start开始记录,stop停止记录,然后通过StopWatch的prettyPrint方法,可直观的输出代码执行耗时,以及执行时间百分比,瞬间感觉比之前的方式高大上了一个档次。

 除此之外,还有以下两个方法shortSummary,getTotalTimeMillis,查看程序执行时间。

 

写法二(apache.commons实现的计时器):

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * <code>StopWatch</code> provides a convenient API for timings.
 * </p>
 *
 * <p>
 * To start the watch, call {@link #start()} or {@link StopWatch#createStarted()}. At this point you can:
 * </p>
 * <ul>
 * <li>{@link #split()} the watch to get the time whilst the watch continues in the background. {@link #unsplit()} will
 * remove the effect of the split. At this point, these three options are available again.</li>
 * <li>{@link #suspend()} the watch to pause it. {@link #resume()} allows the watch to continue. Any time between the
 * suspend and resume will not be counted in the total. At this point, these three options are available again.</li>
 * <li>{@link #stop()} the watch to complete the timing session.</li>
 * </ul>
 *
 * <p>
 * It is intended that the output methods {@link #toString()} and {@link #getTime()} should only be called after stop,
 * split or suspend, however a suitable result will be returned at other points.
 * </p>
 *
 * <p>
 * NOTE: As from v2.1, the methods protect against inappropriate calls. Thus you cannot now call stop before start,
 * resume before suspend or unsplit before split.
 * </p>
 *
 * <p>
 * 1. split(), suspend(), or stop() cannot be invoked twice<br>
 * 2. unsplit() may only be called if the watch has been split()<br>
 * 3. resume() may only be called if the watch has been suspend()<br>
 * 4. start() cannot be called twice without calling reset()
 * </p>
 *
 * <p>This class is not thread-safe</p>
 *
 * @since 2.0
 */
public class StopWatch {

    private static final long NANO_2_MILLIS = 1000000L;


    /**
     * Provides a started stopwatch for convenience.
     *
     * @return StopWatch a stopwatch that's already been started.
     *
     * @since 3.5
     */
    public static StopWatch createStarted() {
        final StopWatch sw = new StopWatch();
        sw.start();
        return sw;
    }

    /**
     * Enumeration type which indicates the status of stopwatch.
     */
    private enum State {

        UNSTARTED {
            @Override
            boolean isStarted() {
                return false;
            }
            @Override
            boolean isStopped() {
                return true;
            }
            @Override
            boolean isSuspended() {
                return false;
            }
        },
        RUNNING {
            @Override
            boolean isStarted() {
                return true;
            }
            @Override
            boolean isStopped() {
                return false;
            }
            @Override
            boolean isSuspended() {
                return false;
            }
        },
        STOPPED {
            @Override
            boolean isStarted() {
                return false;
            }
            @Override
            boolean isStopped() {
                return true;
            }
            @Override
            boolean isSuspended() {
                return false;
            }
        },
        SUSPENDED {
            @Override
            boolean isStarted() {
                return true;
            }
            @Override
            boolean isStopped() {
                return false;
            }
            @Override
            boolean isSuspended() {
                return true;
            }
        };

        /**
         * <p>
         * The method is used to find out if the StopWatch is started. A suspended
         * StopWatch is also started watch.
         * </p>

         * @return boolean
         *             If the StopWatch is started.
         */
        abstract boolean isStarted();

        /**
         * <p>
         * This method is used to find out whether the StopWatch is stopped. The
         * stopwatch which's not yet started and explicitly stopped stopwatch is
         * considered as stopped.
         * </p>
         *
         * @return boolean
         *             If the StopWatch is stopped.
         */
        abstract boolean isStopped();

        /**
         * <p>
         * This method is used to find out whether the StopWatch is suspended.
         * </p>
         *
         * @return boolean
         *             If the StopWatch is suspended.
         */
        abstract boolean isSuspended();
    }

    /**
     * Enumeration type which indicates the split status of stopwatch.
     */
    private enum SplitState {
        SPLIT,
        UNSPLIT
    }
    /**
     * The current running state of the StopWatch.
     */
    private State runningState = State.UNSTARTED;

    /**
     * Whether the stopwatch has a split time recorded.
     */
    private SplitState splitState = SplitState.UNSPLIT;

    /**
     * The start time.
     */
    private long startTime;

    /**
     * The start time in Millis - nanoTime is only for elapsed time so we
     * need to also store the currentTimeMillis to maintain the old
     * getStartTime API.
     */
    private long startTimeMillis;

    /**
     * The stop time.
     */
    private long stopTime;

    /**
     * <p>
     * Constructor.
     * </p>
     */
    public StopWatch() {
        super();
    }

    /**
     * <p>
     * Start the stopwatch.
     * </p>
     *
     * <p>
     * This method starts a new timing session, clearing any previous values.
     * </p>
     *
     * @throws IllegalStateException
     *             if the StopWatch is already running.
     */
    public void start() {
        if (this.runningState == State.STOPPED) {
            throw new IllegalStateException("Stopwatch must be reset before being restarted. ");
        }
        if (this.runningState != State.UNSTARTED) {
            throw new IllegalStateException("Stopwatch already started. ");
        }
        this.startTime = System.nanoTime();
        this.startTimeMillis = System.currentTimeMillis();
        this.runningState = State.RUNNING;
    }


    /**
     * <p>
     * Stop the stopwatch.
     * </p>
     *
     * <p>
     * This method ends a new timing session, allowing the time to be retrieved.
     * </p>
     *
     * @throws IllegalStateException
     *             if the StopWatch is not running.
     */
    public void stop() {
        if (this.runningState != State.RUNNING && this.runningState != State.SUSPENDED) {
            throw new IllegalStateException("Stopwatch is not running. ");
        }
        if (this.runningState == State.RUNNING) {
            this.stopTime = System.nanoTime();
        }
        this.runningState = State.STOPPED;
    }

    /**
     * <p>
     * Resets the stopwatch. Stops it if need be.
     * </p>
     *
     * <p>
     * This method clears the internal values to allow the object to be reused.
     * </p>
     */
    public void reset() {
        this.runningState = State.UNSTARTED;
        this.splitState = SplitState.UNSPLIT;
    }

    /**
     * <p>
     * Split the time.
     * </p>
     *
     * <p>
     * This method sets the stop time of the watch to allow a time to be extracted. The start time is unaffected,
     * enabling {@link #unsplit()} to continue the timing from the original start point.
     * </p>
     *
     * @throws IllegalStateException
     *             if the StopWatch is not running.
     */
    public void split() {
        if (this.runningState != State.RUNNING) {
            throw new IllegalStateException("Stopwatch is not running. ");
        }
        this.stopTime = System.nanoTime();
        this.splitState = SplitState.SPLIT;
    }

    /**
     * <p>
     * Remove a split.
     * </p>
     *
     * <p>
     * This method clears the stop time. The start time is unaffected, enabling timing from the original start point to
     * continue.
     * </p>
     *
     * @throws IllegalStateException
     *             if the StopWatch has not been split.
     */
    public void unsplit() {
        if (this.splitState != SplitState.SPLIT) {
            throw new IllegalStateException("Stopwatch has not been split. ");
        }
        this.splitState = SplitState.UNSPLIT;
    }

    /**
     * <p>
     * Suspend the stopwatch for later resumption.
     * </p>
     *
     * <p>
     * This method suspends the watch until it is resumed. The watch will not include time between the suspend and
     * resume calls in the total time.
     * </p>
     *
     * @throws IllegalStateException
     *             if the StopWatch is not currently running.
     */
    public void suspend() {
        if (this.runningState != State.RUNNING) {
            throw new IllegalStateException("Stopwatch must be running to suspend. ");
        }
        this.stopTime = System.nanoTime();
        this.runningState = State.SUSPENDED;
    }

    /**
     * <p>
     * Resume the stopwatch after a suspend.
     * </p>
     *
     * <p>
     * This method resumes the watch after it was suspended. The watch will not include time between the suspend and
     * resume calls in the total time.
     * </p>
     *
     * @throws IllegalStateException
     *             if the StopWatch has not been suspended.
     */
    public void resume() {
        if (this.runningState != State.SUSPENDED) {
            throw new IllegalStateException("Stopwatch must be suspended to resume. ");
        }
        this.startTime += System.nanoTime() - this.stopTime;
        this.runningState = State.RUNNING;
    }

    /**
     * <p>
     * Get the time on the stopwatch.
     * </p>
     *
     * <p>
     * This is either the time between the start and the moment this method is called, or the amount of time between
     * start and stop.
     * </p>
     *
     * @return the time in milliseconds
     */
    public long getTime() {
        return getNanoTime() / NANO_2_MILLIS;
    }

    /**
     * <p>
     * Get the time on the stopwatch in the specified TimeUnit.
     * </p>
     *
     * <p>
     * This is either the time between the start and the moment this method is called, or the amount of time between
     * start and stop. The resulting time will be expressed in the desired TimeUnit with any remainder rounded down.
     * For example, if the specified unit is {@code TimeUnit.HOURS} and the stopwatch time is 59 minutes, then the
     * result returned will be {@code 0}.
     * </p>
     *
     * @param timeUnit the unit of time, not null
     * @return the time in the specified TimeUnit, rounded down
     * @since 3.5
     */
    public long getTime(final TimeUnit timeUnit) {
        return timeUnit.convert(getNanoTime(), TimeUnit.NANOSECONDS);
    }

    /**
     * <p>
     * Get the time on the stopwatch in nanoseconds.
     * </p>
     *
     * <p>
     * This is either the time between the start and the moment this method is called, or the amount of time between
     * start and stop.
     * </p>
     *
     * @return the time in nanoseconds
     * @since 3.0
     */
    public long getNanoTime() {
        if (this.runningState == State.STOPPED || this.runningState == State.SUSPENDED) {
            return this.stopTime - this.startTime;
        } else if (this.runningState == State.UNSTARTED) {
            return 0;
        } else if (this.runningState == State.RUNNING) {
            return System.nanoTime() - this.startTime;
        }
        throw new RuntimeException("Illegal running state has occurred.");
    }

    /**
     * <p>
     * Get the split time on the stopwatch.
     * </p>
     *
     * <p>
     * This is the time between start and latest split.
     * </p>
     *
     * @return the split time in milliseconds
     *
     * @throws IllegalStateException
     *             if the StopWatch has not yet been split.
     * @since 2.1
     */
    public long getSplitTime() {
        return getSplitNanoTime() / NANO_2_MILLIS;
    }
    /**
     * <p>
     * Get the split time on the stopwatch in nanoseconds.
     * </p>
     *
     * <p>
     * This is the time between start and latest split.
     * </p>
     *
     * @return the split time in nanoseconds
     *
     * @throws IllegalStateException
     *             if the StopWatch has not yet been split.
     * @since 3.0
     */
    public long getSplitNanoTime() {
        if (this.splitState != SplitState.SPLIT) {
            throw new IllegalStateException("Stopwatch must be split to get the split time. ");
        }
        return this.stopTime - this.startTime;
    }

    /**
     * Returns the time this stopwatch was started.
     *
     * @return the time this stopwatch was started
     * @throws IllegalStateException
     *             if this StopWatch has not been started
     * @since 2.4
     */
    public long getStartTime() {
        if (this.runningState == State.UNSTARTED) {
            throw new IllegalStateException("Stopwatch has not been started");
        }
        // System.nanoTime is for elapsed time
        return this.startTimeMillis;
    }

    /**
     * <p>
     * Gets a summary of the time that the stopwatch recorded as a string.
     * </p>
     *
     * <p>
     * The format used is ISO 8601-like, <i>hours</i>:<i>minutes</i>:<i>seconds</i>.<i>milliseconds</i>.
     * </p>
     *
     * @return the time as a String
     */
    @Override
    public String toString() {
        return DurationFormatUtils.formatDurationHMS(getTime());
    }

    /**
     * <p>
     * Gets a summary of the split time that the stopwatch recorded as a string.
     * </p>
     *
     * <p>
     * The format used is ISO 8601-like, <i>hours</i>:<i>minutes</i>:<i>seconds</i>.<i>milliseconds</i>.
     * </p>
     *
     * @return the split time as a String
     * @since 2.1
     */
    public String toSplitString() {
        return DurationFormatUtils.formatDurationHMS(getSplitTime());
    }

    /**
     * <p>
     * The method is used to find out if the StopWatch is started. A suspended
     * StopWatch is also started watch.
     * </p>
     *
     * @return boolean
     *             If the StopWatch is started.
     * @since 3.2
     */
    public boolean isStarted() {
        return runningState.isStarted();
    }

    /**
     * <p>
     * This method is used to find out whether the StopWatch is suspended.
     * </p>
     *
     * @return boolean
     *             If the StopWatch is suspended.
     * @since 3.2
     */
    public boolean isSuspended() {
        return runningState.isSuspended();
    }

    /**
     * <p>
     * This method is used to find out whether the StopWatch is stopped. The
     * stopwatch which's not yet started and explicitly stopped stopwatch is
     * considered as stopped.
     * </p>
     *
     * @return boolean
     *             If the StopWatch is stopped.
     * @since 3.2
     */
    public boolean isStopped() {
        return runningState.isStopped();
    }

}

 

写法三(Scala函数写法):

import org.slf4j.LoggerFactory

/**
  * 类功能描述:Debug日志追踪
  *
  * @author barry create at 18-8-29 下午3:41
  * @version 1.0.0
  */
object Debug {
  val LOGGER = LoggerFactory.getLogger(getClass)
  val counter = collection.mutable.Map[String, Int]() // label -> count
  val times = collection.mutable.Map[String, Long]() // label - time(ns)

  /**
    *追踪代码块
    * @param label 标签名
    * @param codeBlock 代码块
    * @tparam T 返回结果类型
    * @return
    */
  def trace[T](label: String)(codeBlock: => T) = {
    val t0 = System.nanoTime()
    val result = codeBlock
    val t1 = System.nanoTime()
    counter.get(label).map(_counter => counter.put(label, _counter + 1)).orElse(counter.put(label, 1))
    times.get(label).map(cost => times.put(label, cost + (t1 - t0))).orElse(times.put(label, t1 - t0))
    result
  }

  /**
    * 打印日志
    */
  def info(): Unit = {
    LOGGER.warn("FinallyDone...")
    LOGGER.warn(s"counter:${counter}")
    LOGGER.warn(s"times:${times.map { case (label, cost) => (label, cost / 1000000)}}ms")
  }

  /**
    * 重新计数
    */
  def reset(): Unit = {
    counter.clear()
    times.clear()
  }
}

 

参考下面测试代码:

java版本:

 1 /**
 2  * @author WangXueXing create at 19-7-31 下午1:46
 3  * @version 1.0.0
 4  */
 5 public class StopWatchDemo {
 6     public static void main(String[] args){
 7         Debug.trace("方法1调用次数及用时", ()->{
 8             try {
 9                 Thread.sleep(2000);
10             } catch (InterruptedException e) {
11                 e.printStackTrace();
12             }
13             return "";
14         });
15         
16         Debug.trace("方法1调用次数及用时", ()->{
17             try {
18                 Thread.sleep(2000);
19             } catch (InterruptedException e) {
20                 e.printStackTrace();
21             }
22             return "";
23         });
24         
25         Debug.trace("方法2调用次数及用时", ()->{
26             try {
27                 Thread.sleep(2000);
28             } catch (InterruptedException e) {
29                 e.printStackTrace();
30             }
31             return 10;
32         });
33 
34         Debug.info();
35     }
36 }

输出结果:

15:29:32.228 [main] WARN  test.Debug$ - FinallyDone...
15:29:32.361 [main] WARN  test.Debug$ - counter:Map(方法2调用次数及用时 -> 1, 方法1调用次数及用时 -> 2)
15:29:32.364 [main] WARN  test.Debug$ - times:Map(方法2调用次数及用时 -> 2000, 方法1调用次数及用时 -> 4000)ms

  

scala版本:

/**
  * @author WangXueXing create at 19-8-1 下午3:40
  * @version 1.0.0
  */
object StopWatchTest {
  def main(args: Array[String]): Unit = {
    Debug.trace("方法1调用次数及用时")( Thread.sleep(200))
    Debug.trace("方法1调用次数及用时")( Thread.sleep(200))
    Debug.trace("方法2调用次数及用时")( Thread.sleep(200))
    Debug.info()
  }
}

输出结果:

15:43:58.601 [main] WARN  test.stopwatch.Debug$ - FinallyDone...
15:43:58.735 [main] WARN  test.stopwatch.Debug$ - counter:Map(方法2调用次数及用时 -> 1, 方法1调用次数及用时 -> 2)
15:43:58.739 [main] WARN  test.stopwatch.Debug$ - times:Map(方法2调用次数及用时 -> 200, 方法1调用次数及用时 -> 400)ms

  

对比java版本与scala版本,是不是看到scala的简洁及强大了吧!

posted @ 2019-08-01 14:23  BarryW  阅读(3631)  评论(0编辑  收藏  举报