我正在使用线程查询服务器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()
,但我无法找到更好的选择:/
答案 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说
返回的值表示纳秒,因为某些固定但任意的原始时间(可能在未来,因此值可能为负)。
所以你需要获取开始和结束时间之差的绝对值。