Это исходный код для 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()
в конце вашего процесса.
Хотя совместное использование одной и той же переменной может выглядеть странно, это действительно имеет смысл, поскольку splittedTime
из 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 лжец показывает вам 15 секунд в splittedTime: поскольку stop()
обновил, stopTime
переменная getSplitTime()
будет использовать для возврата своего значения. ( первый фрагмент кода )
Обратите внимание на простоту функции split()
( это также почти не отвечает на вопрос OP ). Он отвечает за:
(Проверка, работает ли StopWatch
.) Маркировка нового
stopTime
. Установка
splitState
на
SPLIT
.
И все. Вау, так тяжело, точно часы устали .
TLDR lol
Вызов getSplitTime()
перед остановкой StopWatch
должен показать вам желаемое значение :
stopTime
не будет быть обновленным stop()
еще. - Возвращаемое значение теперь будет соответствовать времени, прошедшему между последним
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()
на остановленном Watch
не вызовет никаких исключений, потому что метод будет проверять только, является ли splitState
SPLIT
.
Путаница может быть вызвана этими двумя фактами:
- Код позволяет
stop()
независимо от SplitState
, делая ваш последний split()
бесполезным без вашего ведома. Бесполезно, я люблю это слово. Пришлось как-то включить это в свой ответ. Futileeee - Это также позволяет вам проверить
splittedTime
на остановленных часах (если они все еще находятся в состоянии SPLIT
), когда он действительно просто вернет общее время, прошедшее между последнее start()
и время остановки. (маленький лжец)
В этом сценарии , где секундомер остановлен и разделен одновременно, , getTime()
и getSplitTime()
всегда будут показывать то же значение при вызове после stop()
.
[Личное и субъективное мнение]
Допустим, у вас есть класс Counters
с разными переменными для проверки прошедшего времени. Вы также хотите выводить общее прошедшее время для каждой операции каждые 60 секунд. В этом примере counters
является экземпляром класса Counters
, который владеет двумя long
переменными: fileTime
и sendTime
, которые будут накапливать время, прошедшее с каждой операции в течение указанного c интервал ( 60 с ). Это просто пример, в котором предполагается, что каждая итерация занимает менее 1000 мс (поэтому всегда будет отображаться 60 секунд прошедшего времени):
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()
и showTimes()
, чтобы очистить приведенный выше код. Он также может управлять переменной elapsedStatsTimer
. Это просто пример для упрощения его поведения.
Для этого варианта использования, в котором вам нужно постоянно измерять различные операции , я думаю, что этот способ проще для использовать и, похоже, имеет аналогичную производительность, поскольку StopWatch
внутренне делает то же самое. Но послушайте, это просто мой способ сделать это :) 1211 * с минутой молчания в честь unsplit()
, что может быть одним из самых неуместных методов, которые я когда-либо видел.
[Личное и субъективное мнение]