Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/226.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Thread.sleep(x)是否足够精确,可以在Android中用作时钟?_Java_Android_Multithreading - Fatal编程技术网

Java Thread.sleep(x)是否足够精确,可以在Android中用作时钟?

Java Thread.sleep(x)是否足够精确,可以在Android中用作时钟?,java,android,multithreading,Java,Android,Multithreading,我有一个单独的线程运行在我的主类。它需要每100毫秒发送一条消息,但恰好每100毫秒发送一条。我想知道它是否足够准确,可以这样使用,或者是否有另一种方法可以让某件事情每秒发生10次 class ClockRun implements Runnable { @Override public void run() { double hourlyRate = Double.parseDouble(prefs.getString("hourlyRate", ""));

我有一个单独的线程运行在我的主类。它需要每100毫秒发送一条消息,但恰好每100毫秒发送一条。我想知道它是否足够准确,可以这样使用,或者是否有另一种方法可以让某件事情每秒发生10次

class ClockRun implements Runnable {

    @Override
    public void run() {
        double hourlyRate = Double.parseDouble(prefs.getString("hourlyRate", ""));
        double elapsedTime = 0;
        do {
            while(clockRun){
                double amount = hourlyRate / 360 /100 * elapsedTime;
                elapsedTime++;
                Bundle clockData = new Bundle();
                clockData.putString("value", String.format("$%.2f", amount));

                Message message = Message.obtain();
                message.setData(clockData);


                handler.sendMessage(message);

                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }while (mainRun);

        Notify.viaToast(getApplication(), "Thread stopped.");

    }
}

不,一点也不准确

从文档中:

(暂时停止) 执行)指定的毫秒数,取决于系统计时器和调度程序的精度和准确性。 换句话说,这种睡眠取决于操作系统或环境,您无法预测操作系统的调度决策,另外,睡眠可以通过中断终止

再次从文档中:

此外,这是没有效率的,因为你将浪费CPU周期只是为了睡觉

将提供更好的精度和性能。
只需将您的任务包装为可调用或可运行,并使用
ScheduledExecutorService
执行它们,有很多教程。

我建议使用ScheduledThreadPoolExecutor的
scheduleAtFixedRate()
方法,因为无论
run()中的代码需要多长时间,它都会在给定的时间触发
要完成的方法

我想应该是这样的:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
            // Do your stuff      
    }
});

ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
ses.scheduleAtFixedRate(runnable, 0, 100, TimeUnit.MILLISECONDS);

即使睡眠是准确的,该代码也不会每100毫秒发送一条消息,而是每100毫秒(运行非睡眠代码的时间超过100秒)发送一次。而且,“每100毫秒准确发送一次”与“每秒准确发送10次”并不相同:后者的要求可以通过执行10次,然后在剩下的时间内睡眠来满足。Android不是实时操作系统。您无法确保“每100毫秒”执行一次操作,因为CPU可能会在该特定时间停止执行其他操作。如果我要编写秒表应用程序,我将使用
postDelayed()
定期(例如每100毫秒)安排主应用程序线程的控制。但随后我会更新秒表UI,以反映实际经过的时间(例如,秒表启动时的
SystemClock.currentTimeMillis()
与现在的
SystemClock.currentTimeMillis()
值之间的差异),而不是假设我每100毫秒就获得一次控制权。这是一个众所周知的问题,因为计时程序已经存在30多年了。@commonware,没有任何操作系统可以确保您每100毫秒执行一次操作。有些人比其他人好,但没有一个是完美的。“实时”一词意味着有计时要求,但并不意味着计时有任何特定的精度。如果你的要求足够宽松,你可以为任何平台编写实时软件(别问我怎么知道。)@shmag18,你的例子最大的问题是
sleep()
不准确,如果你依靠求和sleep()时间来计时,那么你也会求和错误。你的时钟走得越长,它可能离你越远。更好的策略是要求操作系统在循环中每次都进行精确的时间检查(例如,
system.currentTimeMillis()
),然后计算下一次间隔的睡眠时间。您仍然会被一个sleep()错误关闭,但您不会将错误相加。