Я пробовал это:
for(int i =0; i<10; i++)
{
long t1 = System.nanoTime();
try{Thread.sleep(1000);}catch(Exception e){}
double time = (System.nanoTime() - t1)/1000000;
System.out.println(i+") "+time);
}
И вывод этого:
0) 987.0
1) 999.0
2) 999.0
3) 999.0
4) 999.0
5) 1000.0
6) 999.0
7) 997.0
8) 999.0
9) 999.0
Как видно, Thread.sleep()
не совсем точен, так как засыпал на 1000 мс только 1 раз из 10 попыток.
Но я думал, что это займет больше времени, чем 1000 мс, так как потребуется некоторое время, чтобы вычислить значение t1
и time
. Какая-то конкретная причина, по которой он спит меньше времени, а не больше, чем указано? (Мой компьютер точно не мега-суперкомпьютер, подаренный инопланетянами, чтобы вычислять значения t1
и time
в отрицательное время! :P )
Кроме того, как я могу перевести поток в спящий режим на ровно 1000 мс?
.0
происходит просто из методаtoString()
дляDouble
: docs.oracle.com/javase/7/docs/api/java/lang/ - person PeterMmm   schedule 09.01.2016System.nanoTime()
сна в течение 98% времени, которое вы хотите подождать, и продолжайте делать это с оставшимся временем, которое у вас осталось, пока вы не достигнете степени точности, которую считаете приемлемой для ваших нужд. К сожалению, это не сильно поможет вам с точностью менее миллисекунды. В качестве альтернативы, вообще не спите и загружайте процессор на 100%, выполняяwhile (System.nanoTime() < t1 + waitTime) {};
- person flungo   schedule 09.01.2016System.nanoTime()
возвращает длинное значение, деление(System.nanoTime() - t1)/1000000
является длинным делением, дающим длинный результат. Присвоение результата двойной переменной не восстанавливает дробную часть. - person Thomas Kläger   schedule 09.01.2016toString()
, когда объединяете строку с двойным. И, как упомянул Томанс, вы никогда не используете деление с плавающей запятой, потому что оно преобразуется в двойное только в последний момент перед присваиванием. Вместо этого попробуйте(System.nanoTime() - t1)/1000000.0
. - person Sergei Tachenov   schedule 09.01.2016double d = 32.323; System.out.println("d = "+d);
- person dryairship   schedule 09.01.2016toString()
и, конечно, это работает. В первом случае вы присваиваете значениеlong
(вычисленное из выражения RHS) двойному числу, тем самым усекая дробную часть. Затем вы вызываетеtoString()
и, конечно же, он печатает дробную часть, равную нулю. Прочтите литературу о том, как оцениваются выражения Java, может быть, даже JLS. - person Sergei Tachenov   schedule 09.01.2016