我有一个从ArrayBlockingQueue() connectionPool.
获取对象的线程如果ArrayBlockingQueue()为空,则该线程可能被阻塞。要测量调用线程被阻止的时间,我使用以下代码:
long start = System.nanoTime();
DataBaseEndPoint dbep = connectionPool.take();
long end = System.nanoTime();
long elapsed = (end - start)/1000000;
现在,我担心的是,未阻塞的线程可能会开始在多处理器计算机上的不同处理器上运行。在这种情况下,我不完全确定在不同的处理器上使用的'系统定时器'是否相同。 这篇博文(http://www.javacodegeeks.com/2012/02/what-is-behind-systemnanotime.html)表明Linux为每个处理器使用了不同的时间戳计数器(也用于System.nanotime()),这可能会破坏上面例子中的经过时间计算。
使用CLOCK_MONOTONIC标志从clock_gettime读取该值 使用TSC或HPET。与Windows的唯一区别是 Linux甚至没有尝试同步从不同CPU读取的TSC值, 它只是按原样返回它。这意味着价值可以回升 在读取它的CPU的依赖性下向前跳。
此链接(http://lwn.net/Articles/209101/)表明TSC不再用于高分辨率计时器。
...最近更新的高分辨率计时器和动态刻度补丁 set包括禁止使用TSC的更改。好像是 高分辨率计时器和动态刻度功能不兼容 TSC ......
那么,问题是,Linux机器目前使用什么来将值返回到System.nanotime()
?并且,在上述情况下使用System.nanotime()
安全来测量经过的时间(在另一个处理器上启动阻塞的线程)。如果不安全,还有什么选择?
答案 0 :(得分:0)
虚拟机(以及一般生活)的一个重要因素是抽象。线程'执行时间根据核心数量而有所不同;不是在Linux中,也不是在Windows中......我希望我不会误解你的问题。
(虽然我使用的是currentTimeMillis(),但nanime在不同的范围内是相同的,当然)
检查我制作的以下示例:
public class SynchThreads {
public static void main(String[] args) throws InterruptedException {
GreedyTask gtA = new GreedyTask("A");
GreedyTask gtB = new GreedyTask("B");
Thread a = new Thread(gtA);
Thread b = new Thread(gtB);
a.start();
b.start();
a.join();
b.join();
System.out.println(gtA.toString()+" running time: "+gtA.getRunningTime());
System.out.println(gtB.toString()+" running time: "+gtB.getRunningTime());
}
private static class GreedyTask implements Runnable {
private long startedTime, finishedTime, totalRunTime;
private String myName;
public GreedyTask(String pstrName) {
myName = pstrName;
}
public void run() {
try {
startedTime = System.currentTimeMillis();
randomPowerNap(this);
finishedTime = System.currentTimeMillis();
totalRunTime = finishedTime - startedTime;
} catch (Exception e) { System.err.println(e.getMessage()); }
}
public String toString() { return ("Task: " + myName); }
public long getRunningTime() { return this.totalRunTime; }
}
private static synchronized void randomPowerNap(GreedyTask gt) throws InterruptedException {
System.out.println("Executing: "+gt.toString());
long random = Math.round(Math.random()*15000);
System.out.println("Random time for "+gt+" is: "+random);
Thread.sleep(random);
}
}
以下是4核Windows机器中运行的输出:
Executing: Task: A
Random time for Task: A is: 1225
Executing: Task: B
Random time for Task: B is: 4383
Task: A running time: 1226
Task: B running time: 5609 // what's funny about this? this is equal to Btime - Atime
这是在4核Linux机器上运行的:
Executing: Task: A
Random time for Task: A is: 13577
Executing: Task: B
Random time for Task: B is: 5340
Task: A running time: 13579
Task: B running time: 18920 // same results
结论:B总时间增加了当randomPowerNap被A阻塞时必须等待的时间,因此由于虚拟机的硬件抽象,线程看到它们的运行时间没有差异,因为它们都在&#39中运行如果你知道我的意思,那就是虚拟的核心。
我希望这会有所帮助。