- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一个 Java 应用程序,用于通过 UART 连接 (RS422) 与嵌入式设备通信。主机以 5 毫秒为间隔向微 Controller 查询数据。直到最近我一直在使用 ScheduledExecutorService scheduleAtFixedRate 来调用我的通信协议(protocol)方法,但事实证明 scheduleAtFixedRate 对于这种所需的精度级别非常不可靠(正如许多其他帖子所揭示的那样)。从微 Controller 返回的数据中有一个时间戳(以微秒为单位),使我能够独立于 JVM 验证接收到的数据包之间的间隔。不用说,使用 scheduleAtFixedRate 时的间隔变化很大——数据包之间最多 30 毫秒。此外,调度程序随后将尝试通过在一毫秒内多次调用 Runnable 来过度补偿错过的周期(同样,这里的任何人都不会感到惊讶)。
经过一番搜索后,大家似乎一致认为 JVM 根本无法确保任何类型的精确调度。然而,我决定自己做一些实验并想出了这个:
Runnable commTask = () -> {
// volatile boolean controlled from the GUI
while(deviceConnection) {
// retrieve start time
startTime = System.nanoTime();
// time since commProtocol was last called
timeDiff = startTime - previousTime;
// if at least 5 milliseconds has passed
if(timeDiff >= 5000000) {
// handle communication
commProtocol();
// store the start time for comparison
previousTime = startTime;
}
}
};
// commTask is started as follows
service = Executors.newSingleThreadScheduledExecutor();
service.schedule(commTask, 0, TimeUnit.MILLISECONDS);
结果非常棒。相邻时间戳与预期的 5 毫秒间隔的差异从不超过 0.1 毫秒。尽管如此,这种技术似乎有些不对劲,但我还没有想出任何其他有效的方法。我的问题基本上是这种方法是否可行,如果不行,我应该怎么做?
(我正在运行带有 JDK 8_74 的 Windows 10)
最佳答案
根据我在评论中收到的信息,我决定保留我的代码基本不变(我添加到 while 循环的 Thread.yield() 除外)。我已经使用了几个月,对这种方法的性能非常满意。请参阅下面的最终代码。
Runnable commTask = () -> {
// volatile boolean controlled from the GUI
while(deviceConnection) {
// retrieve start time
startTime = System.nanoTime();
// time since commProtocol was last called
timeDiff = startTime - previousTime;
// if at least 5 milliseconds has passed
if(timeDiff >= 5000000) {
// handle communication
commProtocol();
// store the start time for comparison
previousTime = startTime;
}
Thread.yield();
}
};
// commTask is started as follows
service = Executors.newSingleThreadScheduledExecutor();
service.execute(commTask);
关于Java "scheduleAtFixedRate"替代解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35373705/
我尝试每小时执行一次代码 这是针对applicationRunner中的java,可以在服务器启动时运行。 @Component public class TestApplicationRunner
我在程序中使用方法scheduleAtFixedRate(Timer类)。它每秒运行一次,但有时此方法变得非常快(每秒执行 3 - 4 次)。 但是我在网络上做了一些研究,发现了这个: 从 Andro
日志: [pool-1-thread-1] TRACE apns.ApnsPushConnection - 输入方法 queryFeedbackService 参数[pool-3-thread-1]
我正在阅读一本 java8 书籍,发现了 ScheduleAtFixedRate 和 ScheduledExecutorService 中的 scheduleWithFixedDelay 方法之间的区
我们需要通过 Java 程序关注 PC 时钟。为此,我们每 500 毫秒使用 ScheduleAtFixedRate() 调度一个 Runnable。我们每次都从中调用 System.currentT
我正在编写一个应用程序,它生成随机数并在 Android 屏幕上显示它们(一个接一个)。这是 Activity java fragment 。 public class Scada extends A
public class MyTimerTask extends TimerTask{ @Override public void run() { int i = 0;
我有一个 Java 应用程序,用于通过 UART 连接 (RS422) 与嵌入式设备通信。主机以 5 毫秒为间隔向微 Controller 查询数据。直到最近我一直在使用 ScheduledExecu
我有 TextView 来频繁更新时间,工作正常,但问题是我想根据不同的条件更改计划时间,但我无法更改计划时间。它继续在最初设置的时间。 private Long mPeriod = Long.par
我正在研究 Java 类 ScheduledExecutorService 的 scheduleAtFixedRate 方法。 这是我的可疑代码: ScheduledExecutorService s
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import
我正在尝试使用 ScheduledExecutorService 类的方法 scheduleAtFixedRate 进行示例。代码是: ScheduledExecutorService service
我创建了一个可运行的类并创建了一个线程,但具有唯一的名称,但是当我通过 executor.scheduleAtFixedRate 发送该线程时,它创建了自己的线程,我不明白这是为什么? 我试着阅读这里
当我定期执行一项耗时的任务时,结果没有达到我的预期。 public static void main(String[] args) { ScheduledExecutorService sch
我正在使用ScheduledExecutorService使用 scheduleAtFixedRate 方法每小时提供一次数据库更新。问题是它逐渐变得更晚 - 在长期服务中我一直在记录它并且每天大约一
这是我的固定速率计时器代码。当 Activity 进入 onPause(); 时,我可以暂停这个计时器吗?如果是这样,那么您建议我在 onPause(); 方法中放入什么,当应用程序进入 onResu
Runnable runPickWinner = new Runnable() { @Override public void run() {
因为我每秒都在执行时间紧迫的任务,所以我比较了几种方法以找到确保我的任务真正以固定时间步长执行的最佳方法。在计算所有方法的误差标准推导后,似乎使用方法 scheduledExecutorService
final Runnable refresh = new Refresh(params...); service = Executors.newScheduledThreadPool(1); serv
我的代码是: ou=100 final Timer t=new Timer(); TimerTask tt=new TimerTask() { @Overrid
我是一名优秀的程序员,十分优秀!