System.currentTimeMillis() 和sleep 存在误差原因与解决方案

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;
            }
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值