2015-11-14 76 views
1

我正在做模拟项目,其中有数百个CPU绑定作业运行10到50毫秒。作业是一个Runnable对象,具有指定的运行时间,作业将使CPU保持忙碌状态。线程池中有10个线程正在等待工作到达。我将请求速率设置为每秒40个请求,并将所有作业运行时间设置为10ms。但结果非常糟糕。所有作业运行至少15ms。没有工作运行10毫秒。我用15ms的工作测试了实验,并得到了正确的结果。为什么10ms作业至少运行15ms?(我正在使用WINDOWS8)。为什么小于15ms的忙等待不一致?

public class CpuBoundJob implements Runnable { 
long runningTime 
    public CpuBoundJob(long runningTime) { 
     this.runningTime=runningTime; 
      } 
    @Override 
    public void run() { 

     long timeToWait = this.runningTime; 
     long startTime = System.currentTimeMillis(); 
     while(startTime + timeToWait > System.currentTimeMillis()); 
} 
} 
+1

您的系统计时器的分辨率可能是15ms。你可以尝试['System.nanoTime()'](http://docs.oracle.com/javase/8/docs/api/java/lang/System.html#nanoTime--),但它可能没有更多分辨率。链接的Javadoc说(部分)*除了分辨率至少和currentTimeMillis()一样好,没有任何保证。* –

回答

1

在许多系统(特别是视窗,IIRC),System.currentTimeMillis()由时钟只精确到15毫秒左右的支持。

但是,它更糟糕:System.currentTimeMillis()措施时间自从Unix时代由系统时钟测量。因此,如果您更改计算机上的时间(例如,由于将系统时钟同步到时间源或闰秒或其他任何事项),则currentTimeMillis()可以随意向前或向后跳转大量时间。

如果你想测量经过时间,NEVER使用currentTimeMillis()。改为使用System.nanoTime()。作为奖励,在大多数系统上,它的调用也相当便宜,并且更精确。

+0

我已经使用System.nanoTime(),它比System.currentTimeMillis )。使用System.nanoTime()时,有些作业甚至运行0ms。 –

+0

@MuhammadAbdullah当纳秒时间也有15ms的结果时,那么从那个时钟源的某个时刻从0跳到15会发生。如果你不走运,那就是录制startTime和检查循环之间的那一刻。有效地等待0时间,但你无能为力。当你测试'nanoTime'时,你确定把你的等待时间乘以1000000? – zapl

+0

@MuhammadAbdullah:在Windows 8上,'nanoTime()'应该有更好的分辨率。你可以在不是这种情况下显示代码吗? –