在两个长动作之间获得负的持续时间?

时间:2013-11-13 10:04:34

标签: java multithreading url duration

我正在使用线程查询服务器URL,并且我正在计算查询此服务器所需的时间并获得用作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);
    }
}

你知道为什么吗?

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

  使用nanoTime的一个问题(在Windows上,无论如何是Sun JDK6)就是这样   返回的值取决于执行线程的CPU核心如果   线程开始在一个核心上执行并在另一个核心上完成,   你的号码有点偏离。我有像长启动=的代码   System.nanoTime(); doIt方法(); long elapsedNanos = System.nanoTime() -   开始;并且结束了过去的纳诺斯是消极的。 -

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

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

2 个答案:

答案 0 :(得分:1)

所以我拿了你的代码,在最后加了System.out.println("Time: " + (duration == null ? "aborted" : duration));并运行了几千次......它从来没有返回任何东西,甚至是远程负面的。我甚至试图评论连接部分,并且最短时间接近120,000ns。

如果你有一个负面的时间,你的代码中有一些你没有发布的东西,或者是你的操作系统/ JVM实现的错误。 Java和System.nanoTime()正在完美地完成它的工作。

关于在不同线程中计算时间时的负时间差异的评论很有意思,但即使发生了这种情况,“稍微偏离”部分将更像是+/- 10或100 ns,绝对不是> 100,000ns。

答案 1 :(得分:0)

nanoTime的javadoc说

  

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

所以你需要获取开始和结束时间之差的绝对值。

相关问题