2013-11-13 4 views
2

Я запрашиваю URL-адрес сервера с помощью Thread, и я рассчитываю время, затрачиваемое на запрос этого сервера, и получаю ответ, который будет использоваться как response time, но иногда возвращаемое время отрицательное, и этого не должно произойти!Получение отрицательной продолжительности между двумя длительными действиями?

Я мог предположить, что при сбое соединения это происходит так быстро, но для меня вызов двух последователей System.nanoTime() никогда не должен быть ниже, по крайней мере, 0!

Вот мой код:

final long startTime = System.nanoTime(); 
ExecutorService executor = Executors.newFixedThreadPool(1); 

Connector connector = new Connector(url); 
String response = null; 
Long duration = null; 

try { 
    Future<String> future = executor.submit(connector); 
    response = future.get(Connector.timeout, TimeUnit.MILLISECONDS); 

    duration = Long.valueOf(System.nanoTime() - startTime); 
} 
catch (Exception e) {} 

executor.shutdown(); 

// Here, duration is sometimes negative ! 

И Connector.java:

public class Connector implements Callable<String> { 
    public final static int timeout = 2500; // WE use a timeout of 2.5s, which should be enough 

    private String urlStr; 

    public Connector(String url) { 
     this.urlStr = url; 
    } 

    @Override 
    public String call() throws Exception { 
     URL url = new URL(urlStr); 

     HttpURLConnection connection = (HttpURLConnection)url.openConnection(); 
     connection.setConnectTimeout(timeout - 50); 
     connection.setRequestMethod("GET"); 
     connection.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux i686; rv:21.0) Gecko/20100101 Firefox/21.0"); 
     connection.connect(); 

     int code = connection.getResponseCode(); 
     connection.disconnect(); 
     return String.valueOf(code); 
    } 
} 

Есть ли у вас какие-либо идеи, почему?

Update: На этой S.O. question первый комментарий (по @gustafc) первого ответа (Дэвид-Джонстон) очень интересно:

Один Гоча (на Windows, вес ВС JDK6,. в любом случае) с nanoTime - это то, что Возвращаемое значение зависит от ядра ЦП, выполняющего поток. Если нить начинает выполняться на одном сердечнике и заканчивается на другом сердечнике, ваши номера будут несколько за пределами. У меня был код как long start = System.nanoTime(); сделай это(); long elapsedNanos = System.nanoTime() - start; и закончились с прошлым, что отрицательно. -

Я запускаю свою машину под Linux Fedora, но, возможно, это то, что происходит.

Очевидно, что проблема с System.nanoTime(), но я не смог найти лучшую альтернативу:/

+0

«Длинные действия» - как долго? если я правильно помню '.nanoTime()' переполняется через 300 лет ...:-) –

+0

Ahah nice, я сказал между 0ms 2500ms: p –

+0

Я не думаю, что это проблема, но вы могли бы попытаться устранить автобоксинг, сделав вместо этого 'длительность'' долгим'? –

ответ

0

Так я взял код, добавил System.out.println("Time: " + (duration == null ? "aborted" : duration)); до конца и запустить его в несколько тысяч раз ... он никогда ничего не возвращал, даже отдаленно отрицательный. Я даже попытался прокомментировать часть соединения, и снова минимальное время было около 120 000 нс.

Если у вас когда-либо было отрицательное время, в вашем коде есть что-то, что вы не опубликовали, или это ошибка в вашей операционной системе/реализации JVM. Java и System.nanoTime() делают свою работу отлично.

Ваш комментарий об отрицательных временных различиях при расчете времени в разных потоках интересен, но даже если это происходит, часть «немного выключена» будет больше похожа на +/- 10 или 100 нс, а определенно не на 100 000 нс.

+0

Это то, что я предполагаю , он НЕ МОЖЕТ быть под 0ns. Теперь я переключился на «ThreadMXBean» для получения «CurrentThreadCpuTime» и запустил его. Чем ниже я получаю 0. Теперь я вызываю эту проверку у аккера Akka, который также использует «ThreadPool» (через «ExecutorService»). Это означает, что у меня есть 10 потоков (на данный момент я определен как 10), которые генерируют 1 Thread (код выше). Может быть, это слишком поточно? –

1

документация Javadoc для nanoTime говорит

Возвращаемое значение представляет наносекунды с некоторым фиксированным, но произвольным момента времени происхождения (возможно, в будущем, так что значения могут быть отрицательными).

Таким образом, вам нужно будет принять абсолютное значение разницы между временем начала и окончания.

Смежные вопросы