这是(它在内部调用这个其他函数)的源代码:getSplitTime()
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;
}
所以它会返回stopTime-startTime
。当心stopTime
。是骗子让你困惑。
这是代码stop()
:
public void stop() {
if (this.runningState != State.RUNNING && this.runningState != State.SUSPENDED) {
throw new IllegalStateException("Stopwatch is not running. ");
}
if (this.runningState == State.RUNNING)
{
//is this the same stopTime getSplitTime uses? yep, it is
this.stopTime = System.nanoTime();
}
this.runningState = State.STOPPED;
}
那会发生什么?
调用会stop()
更新stopTime
变量并使秒表“忘记”上次拆分的时间。
两者split()
和stop()
修改相同的变量 ,当您在进程结束stopTime
时调用时,该变量会被覆盖。stop()
尽管共享同一个变量可能看起来很奇怪,但它确实很有意义,因为 ansplittedTime
永远StopWatch
不应该大于总经过时间。所以这是一个关于在StopWatch
.
这是 的代码split()
,以便看到这两种方法都使用stopTime
:
public void split() {
if (this.runningState != State.RUNNING) {
throw new IllegalStateException("Stopwatch is not running. ");
}
this.stopTime = System.nanoTime(); // you again little f..
this.splitState = SplitState.SPLIT;
}
这就是为什么这个可爱的 Apache 骗子会在 splittedTime 上显示 15 秒:因为stop()
更新后的stopTime
变量getSplitTime()
将用于返回其值。(第一个代码片段)
请注意函数的简单性split()
(这也几乎不能回答 OP 的问题)。它负责:
- 检查是否
StopWatch
正在运行。
- 标记一个新的
stopTime
.
- 设置
splitState
为SPLIT
.
TLDR lol
getSplitTime()
在停止之前调用StopWatch
应该向您显示所需的值:
stopTime
暂时不会更新stop()
。
- 返回值现在将匹配 last
split()
和startTime
.
一些例子:(是的,周六晚上编辑,因为我需要社交生活)
StopWatch stopwatch = StopWatch.createStarted();
do something for 5 seconds
stopwatch.split(); //stopTime is updated [by split()]
System.out.println(stopwatch.getSplitTime()); // will show 5 seconds
do something for 10 seconds
System.out.println(stopwatch.getSplitTime()); // will also show 5 seconds
stopwatch.stop(); //stopTime is updated again [by stop()]
System.out.println(stopwatch.getTime()); // 15s
System.out.println(stopwatch.getSplitTime()); // 15s
另一个:
StopWatch stopwatch = StopWatch.createStarted();
do something for 5 seconds
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 5s
do something for 10 seconds
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 15s
do something for 1 second
stopwatch.stop();
System.out.println(stopwatch.getTime()); // 16s
最后一个。嘲笑时间sleeps
,只是为了好玩,你知道的。我太无聊了,我真的导入了 apache jar 以便在本地进行测试:
StopWatch stopwatch = StopWatch.createStarted();
Thread.sleep(5000);
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 5s
Thread.sleep(10000);
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 15s
stopwatch.reset(); // allows the stopWatch to be started again
stopwatch.start(); // updates startTime
Thread.sleep(2000);
stopwatch.split();
System.out.println(stopwatch.getSplitTime()); // 2s
Thread.sleep(1000);
stopwatch.stop();
System.out.println(stopwatch.getTime()); // 3s
System.out.println(stopwatch.getSplitTime()); // 3s
//it was so fun putting the sleeps
请注意,调用getSplitTime()
stopWatch
不会引发任何异常,因为该方法只会检查splitState
is 是否SPLIT
。
混淆可能是由以下两个事实引起的:
- 该代码允许您
stop()
不管SplitState
,使您的最后一个split()
徒劳无功而你不知道。徒劳的,我喜欢这个词。不得不以某种方式将其包含在我的答案中。徒劳的
- 它还允许您检查
splittedTime
停止的手表(如果它仍然处于开启SPLIT
状态),它实际上只会返回上次start()
和停止时间之间的总经过时间。(小骗子)
在这种情况下,秒表同时停止和拆分,getTime()
并且getSplitTime()
在调用 after 时始终显示相同的值stop()
。
[个人和主观意见]
假设您有一个Counters
具有不同变量的类来检查经过的时间。您还希望每 60 秒输出每个操作的总经过时间。在此示例中,counters
是一个拥有两个变量的Counters
类的实例:和,它将在特定时间间隔 ( 60 秒) 内累积每个操作中经过的时间。这只是一个假设每次迭代时间少于 1000 毫秒的示例(因此它总是显示经过时间为 60 秒):long
fileTime
sendTime
long statsTimer = System.currentTimeMillis();
while (mustWork)
{
long elapsedStatsTimer = System.currentTimeMillis()-statsTimer; //hits 60185
if (elapsedStatsTimer > 60000)
{
//counters.showTimes()
System.out.println("Showing elapsed times for the last "+
(elapsedStatsTimer/1000)+ " secs"); //(60185/1000) - 60 secs
System.out.println("Files time: "+counters.fileTime+" ms"); //23695 ms
System.out.println("Send time : "+counters.sendTime+" ms"); //36280 ms
long workTime = counters.sendTime+counters.fileTime;
System.out.println("Work time : "+workTime+" ms"); //59975 ms
System.out.println("Others : "+(elapsedStatsTimer-workTime)+" ms"); //210 ms
//counters.reset()
counters.fileTime=0;
counters.sendTime=0;
statsTimer= System.currentTimeMillis();
}
long timer = System.currentTimeMillis();
//do something with a file
counters.fileTime+=System.currentTimeMillis-timer;
timer = System.currentTimeMillis();
//send a message
counters.sendTime+=System.currentTimeMillis()-timer;
}
Counters
该类可以实现reset()
and函数,showTimes()
以清理上面的代码。它还可以管理elapsedStatsTimer
变量。这只是简化其行为的示例。
对于这个需要持续测量不同操作的用例,我认为这种方式更易于使用,并且似乎具有相似的性能,因为StopWatch
内部制作完全相同。但是,嘿,这只是我的方式:)。
我将以一种光荣和徒劳的方式接受对这一观点的反对票。
我很想以一分钟的沉默结束,以纪念unsplit()
,这可能是有史以来最不相关的方法之一。
[/个人主观意见]
刚刚注意到TLDR
部分实际上比上一部分大:_)