2

我写了一个多线程程序,它同时有两到四个线程。其中一个线程是时间关键线程,每 500 毫秒调用一次,不允许延迟超过 10 毫秒。但是当其他线程有更多负载时,我发现出现了一些延迟,大约是两毫秒。(打印时间戳显示)所以,我担心运行很长时间后它会延迟超过10毫秒,除了检查时间戳,并调整循环间隔以确保时间不延迟超过10毫秒,有什么方法可以让它安全吗?

谢谢。

4

5 回答 5

4

听起来你需要实时 Java

于 2012-04-17T06:45:21.207 回答
2

如果时间很关键,我会在专用于该线程的核心上使用忙等待。大多数情况下,这会给您 << 10 微秒的抖动。它有点极端,将导致逻辑​​线程不用于其他任何事情。

这是我使用的图书馆。您可以使用它来保留逻辑线程或整个内核。https://github.com/peter-lawrey/Java-Thread-Affinity

通过在 Linux 上的 grub.conf 中使用 isolcpus=,您可以确保逻辑线程或核心不用于任何其他用途(除了 100 Hz 计时器和电源管理,它们相对较小且延迟 < 2 us)

于 2012-04-17T06:59:41.553 回答
1

您可以设置线程优先级:

myCriticalThread.setPriority(Thread.MAX_PRIORITY);
otherThread.setPriority(Thread.NORM_PRIORITY); // the default
yetAnotherThread.setPriority(Thread.MIN_PRIORITY);

但它并不能真正保证任何事情。

于 2012-04-17T06:41:17.347 回答
0

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.

于 2012-04-17T06:47:36.133 回答
0

爬上超时:

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

于 2012-04-17T11:46:49.087 回答