2

我正在使用 Thread 查询服务器 URL,并且正在计算查询该服务器并获得用作响应response time的时间,但有时,返回的时间是负数,这不应该发生!

我可以假设这是连接失败并且发生得如此之快的时候,但是对我来说,调用两个 consectireSystem.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);
    }
}

你知道为什么吗?

更新:在这个SO 问题上,第一个答案(由 david-johnstone 提供)的第一条评论(由 @gustafc 提供)非常有趣:

nanoTime 的一个问题(在 Windows w. Sun JDK6 上,无论如何)是返回的值取决于执行线程的 CPU 内核如果线程开始在一个核心上执行并在另一个核心上完成,那么您的数字会有些偏离。我有类似 long start = System.nanoTime(); 的代码 做();long elapsedNanos = System.nanoTime() - 开始;最后以 elapsedNanos 为负数。——</p>

我在 Linux Fedora 版本下运行我的机器,但也许这就是正在发生的事情。

显然,问题出在System.nanoTime()但我找不到更好的选择:/

4

2 回答 2

1

所以我拿了你的代码,System.out.println("Time: " + (duration == null ? "aborted" : duration));在最后加了一个,然后运行了几千次……它从来没有返回任何东西,甚至是负面的。我什至尝试注释掉连接部分,最短时间再次接近 120,000ns。

如果你有过消极的时间,要么是你的代码中有一些你没有发布的东西,要么是你的操作系统/JVM 实现的错误。Java 并且System.nanoTime()做得非常好。

您在计算不同线程中的时间时对负时差的评论很有趣,但即使发生这种情况,“有点偏离”部分更像是 +/- 10 或 100 ns,绝对不会 >100,000ns。

于 2013-11-13T12:10:59.107 回答
0

nanoTime 的 javadoc 说

返回的值表示自某个固定但任意的原始时间以来的纳秒(可能在将来,因此值可能为负数)。

因此,您需要获取开始时间和结束时间之间差异的绝对值。

于 2014-05-20T18:00:43.877 回答