【发布时间】:2013-11-13 10:04:34
【问题描述】:
我正在使用线程查询服务器 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 w. Sun JDK6 上,无论如何)是 返回的值取决于执行线程的 CPU 内核。 如果 线程开始在一个核心上执行并在另一个核心上结束, 你的数字会有些偏离。我有像long start这样的代码= System.nanoTime();做(); long elapsedNanos = System.nanoTime() - 开始;最后以 elapsedNanos 为负数。 ——
我在 Linux Fedora 版本下运行我的机器,但也许这就是正在发生的事情。
很明显,问题出在System.nanoTime(),但我找不到更好的选择:/
【问题讨论】:
-
“长时间动作” - 多长时间?如果我没记错的话
.nanoTime()在大约 300 年后溢出...... :-) -
啊,很好,我说的是 0ms 到 2500ms 之间:p
-
我认为这不是问题,但您可以尝试通过将
duration改为long来消除自动装箱吗? -
duration 可以为 null 如果线程在运行太久后被杀死:/
-
相反,我使用
duration = Long.valueOf(System.nanoTime() - startTime);来避免自动装箱
标签: java multithreading url duration