Расписание времени в java с Thread.sleep

  import java.util.Date;

  import javax.xml.crypto.Data;

  public class Task1 {
    public static void main(String[] args) {
      // run in a second
      final long timeInterval = 4000;
      Data now = null;
      Runnable runnable = new Runnable() {
        public void run() {
          while (true) {
            // ------- code for task to run
            System.out.println("Hello !!"+new Date());
            for(int i=0;i<10000;i++){
              System.out.println("Hello !!");
            }

            // ------- ends here
            try {
              Thread.sleep(timeInterval);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
       }

      };

      Thread thread = new Thread(runnable);
      thread.start();
    }
  }

Я прочитал учебник по планированию потоков. Я хочу понять, что код работает нормально и выполняет поток через 4 секунды, но если время, затрачиваемое циклом for, предположим, составляет 1 секунду, тогда общее время будет 1 + 4 5 секунд . Я не хочу, чтобы служба исполнителя. Просто обычный класс Thread. Кто-нибудь может объяснить, как работает эта программа.


person coder25    schedule 30.09.2016    source источник


Ответы (1)


Вы правы в том, что sleep является дополнением ко времени, уже затраченному на цикл.

Даже если вы рассчитали оставшееся время сна, это все равно может занять больше времени, поскольку нет никакой гарантии относительно того, как быстро сон проснется. Иногда это может быть на десятки миллисекунд позже.

Что ExecutorService делает, так это вычисляет, когда он должен выйти из первого запуска, и гарантирует, что любые задержки не накапливаются. Он использует System.nanoTime(), поэтому исправления в настенных часах не влияют на период.

person Peter Lawrey    schedule 30.09.2016
comment
Мне задали этот вопрос в интервью, как лучше всего решить эту проблему, чтобы выполнить поток после определенного интервала без исполнителя. - person coder25; 30.09.2016
comment
@coder25, очевидно, лучший способ - использовать ScheduledExecutorService или делать то, что он делает, а именно брать System.nanoTime() в начале и вычислять, как долго он должен спать каждый раз, чтобы избежать накопленных ошибок. Если важны настенные часы, вы можете использовать System.currentTimeMillis() - person Peter Lawrey; 30.09.2016