java定时器:如何选择+有哪些限制?

时间:2010-01-05 16:46:10

标签: java timer

我需要编写一些代码来使用rxtx进行压力测试RS232通信(注意:这个问题不是关于串口通信,所以请不要去那里),我想定期使用某种计时器任务发送字节。

网上是否有任何关于哪种计时器类用于各种应用程序的指南?我不确定是否应该使用javax.swing.Timerjava.util.Timerjava.util.concurrent.ScheduledExecutorService或其他内容。

他们开始崩溃的频率是多少?我猜它是沿着操作系统时间片的行(忘记它在Windows中的含义,1毫秒-10毫秒似乎是我记得的)。我想以最快的频率运行,这不会给我的PC带来问题;我总是可以一次向串口吐出更多的字节,我只想以尽可能多的周期性方式来做。

3 个答案:

答案 0 :(得分:1)

不要使用Swing计时器;这是早期Swing时代的一段时间。

ScheduledExecutorService是剩下的两个竞争者中更通用和可配置的。它接受纳秒精度,但当然不能提供任何比毫秒级精度更好的平台。您需要一个实时JVM才能达到纳秒精度。

答案 1 :(得分:0)

如果你想要一个高频但准确的频率,我不会使用计时器。

我曾在德尔福做过类似的事情,为步进电机提供快速脉冲。我可以随意咀嚼尽可能多的CPU时间,所以我运行了一个紧密的循环,检查Windows的高精度计时器,直到适当的时间过去,然后做了我需要的操作。

在Java中不太方便,但我推荐使用System.nanoTime()的类似方法。

您可能会发现错过了最后一次标记。如果是这样,以某种方式处理它。无论如何要么快点行动,要么做任何需要做的事情以弥补错误 - 也许等待整个角色空间通过,或者其他什么。此外,您可能希望修改下一个事件的时间间隔。无论如何准确地处理正常抖动都需要。换句话说。

如果你没有在你的循环中做很多对象创建,那么你的垃圾收集器应该没有明智的理由,所以你的时间有合理的机会保持准确。


<强>更新

Jonathan Feinberg告诫我,ScheduledExecutorService是为这种事做的。我认为它不适合OP的高频率,高精度要求。

我在Sun论坛中有人抱怨accuracy problems using this technique:他的重复率仅为200毫秒,但他的延迟时间超过1秒!

Java方法的问题在于,它使用操作系统的设施以大多数跨平台的方式执行此操作,并且不会对系统的其他部分产生负面影响。这些都是妥协;如果您优先快速准确地获取大量事件,并且您对约束有一些余地,则可以构建一个更好的解决方案。这正是我概述的内容。

答案 2 :(得分:0)

为什么不创建自己的线程?

public MyThread extends Thread {
    int frequency = 10; // number per second
    AtomicBoolean shutDown = new AtomicBoolean();

    public void run() {
        while (!shutDown.get()) {
            long startTime = System.nanoTime() / 1000000;
            try {
                performAction();
            } catch (Exception e) {
                System.err.println(e.toString());
            }
            long elapsedTime = startTime - System.nanoTime() / 1000000;

            long sleepTime = 1000 / frequency - elapsedTime;
            if (sleepTime > 0) {
                try {
                    Thread.sleep(sleepTime);
                } catch (InterruptedException e) {
                    // ignored
                }
            }
        }
    }
}

如果必须提高Windows系统上计时器的分辨率,可以使用Thread.sleep(Long.MAX_VALUE) technique