System.currentTimeMillis() 与sleep()存在误差。
精度跟系统相关,10ms-15ms为常见误差,多媒体操作多用 System.nanoTime() 返回纳秒值。
即用 System.nanoTime() /1000000L 替换 System.currentTimeMillis()
参考jdk文档:在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
当然计时器应该积极使用timer,因为它所使用的是wait()而非sleep(),但是仍然存在时钟摇摆,线程调度的误差 。
假如只对调用总数要求高,对时间间隔允许误差的话可以加入如下算法保证调用总数精准,动态补齐 sleep的时间。
例如:
假如想要一个时钟每隔33.3333毫秒执行,执行间隔可以不精准,但执行总数一定要是1秒30次;
private class VideoRecordThread extends Thread {
final private int spaceArray[]= {32,33,35};
private int spaceindex = 0;
private long lastspaceTime = 0;
private boolean mState = true;
@Override
public void run() {
while (mState) {
if(spaceindex >2)
spaceindex = 0;
mReadTime = spaceArray[spaceindex++];
/*
*do something
*/
long deviation = mLastTime - mNowTime -lastspaceTime;
mNowTime = System.nanoTime()/1000000L;
long spaceTime = mReadTime - (mNowTime - mLastTime) - deviation;
if(spaceTime > 2*mReadTime || spaceTime<0)
spaceTime = mReadTime;
try {
sleep(spaceTime);
lastspaceTime = spaceTime;
} catch (InterruptedException e) {
e.printStackTrace();
}
mLastTime = System.nanoTime()/1000000L;
}
}
public void stop();
{
mState = false;
}
}