我写了一个多线程程序,它同时有两到四个线程。其中一个线程是时间关键线程,每 500 毫秒调用一次,不允许延迟超过 10 毫秒。但是当其他线程有更多负载时,我发现出现了一些延迟,大约是两毫秒。(打印时间戳显示)所以,我担心运行很长时间后它会延迟超过10毫秒,除了检查时间戳,并调整循环间隔以确保时间不延迟超过10毫秒,有什么方法可以让它安全吗?
谢谢。
我写了一个多线程程序,它同时有两到四个线程。其中一个线程是时间关键线程,每 500 毫秒调用一次,不允许延迟超过 10 毫秒。但是当其他线程有更多负载时,我发现出现了一些延迟,大约是两毫秒。(打印时间戳显示)所以,我担心运行很长时间后它会延迟超过10毫秒,除了检查时间戳,并调整循环间隔以确保时间不延迟超过10毫秒,有什么方法可以让它安全吗?
谢谢。
听起来你需要实时 Java
如果时间很关键,我会在专用于该线程的核心上使用忙等待。大多数情况下,这会给您 << 10 微秒的抖动。它有点极端,将导致逻辑线程不用于其他任何事情。
这是我使用的图书馆。您可以使用它来保留逻辑线程或整个内核。https://github.com/peter-lawrey/Java-Thread-Affinity
通过在 Linux 上的 grub.conf 中使用 isolcpus=,您可以确保逻辑线程或核心不用于任何其他用途(除了 100 Hz 计时器和电源管理,它们相对较小且延迟 < 2 us)
您可以设置线程优先级:
myCriticalThread.setPriority(Thread.MAX_PRIORITY);
otherThread.setPriority(Thread.NORM_PRIORITY); // the default
yetAnotherThread.setPriority(Thread.MIN_PRIORITY);
但它并不能真正保证任何事情。
There is no guarantee that your thread isn't delayed, because the OS may decide to give other processes precedence (unless you put effort in setting up a complete real-time system including a modified OS). That being said, for basic tasks, you should use a ScheduledExecutorService like this:
class A {
private final ScheduledExecutorService exe = Executors.newScheduledThreadPool(1);
public void startCriticalAction(Runnable command) {
this.exe.scheduleAtFixedRate(command, 100, 100, TimeUnit.MILLISECONDS);
}
public void shutdown() {
this.exe.shutdown();
}
}
The executor service will do its best to execute the task every 100ms. You should not develop this functionality yourself, because a lot of things can go wrong.
爬上超时:
waitFor(int timeout)
{
dateTime wallTimeEnd;
wallTimeEnd=now()+(msToDateTime(timeout));
int interval=timeout/2;
while(true){
if(interval>10){
sleep(interval);
interval=dateTimeToMs(wallTimeEnd-now()) / 2;
}
else
{
do{
sleep(0);
interval=dateTimeToMs(wallTimeEnd-now());
}while(interval>0);
}
}
这只会浪费一个内核 5-10ms