java: запуск функции через определенное количество секунд


У меня есть определенная функция, которую я хочу выполнить через 5 секунд. Как я могу сделать это на Java?

Я нашел javax.качать.таймер, но я не могу понять, как его использовать. Похоже, я ищу что-то более простое, чем этот класс предоставляет.

пожалуйста, добавьте простой пример использования.

10 106

10 ответов:

new java.util.Timer().schedule( 
        new java.util.TimerTask() {
            @Override
            public void run() {
                // your code here
            }
        }, 
        5000 
);

EDIT:

документация говорит:

после того, как последняя живая ссылка на объект Timer исчезает и все невыполненные задачи завершили выполнение, поток выполнения задачи таймера завершается изящно (и становится объектом сборки мусора). Однако это может занять сколь угодно много времени.

что-то вроде этого:

// When your program starts up
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();

// then, when you want to schedule a task
Runnable task = ....    
executor.schedule(task, 5, TimeUnit.SECONDS);

// and finally, when your program wants to exit
executor.shutdown();

существуют различные другие заводские методы на Executor что можно использовать, если вы хотите больше потоков в пуле.

и помните, что важно завершить работу исполнителя, когда вы закончите. Элемент shutdown() метод будет полностью закрыть пул потоков, когда последняя задача будет завершена, и будет блокировать, пока это не произойдет. shutdownNow() немедленно завершит работу пула потоков.

пример использования javax.swing.Timer

Timer timer = new Timer(3000, new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent arg0) {
    // Code to be executed
  }
});
timer.setRepeats(false); // Only execute once
timer.start(); // Go go go!

этот код будет выполнен только один раз, и выполнение происходит в 3000 МС (3 секунды).

как упоминает camickr, вы должны искать"как использовать таймеры качели" для краткого введения.

мой код выглядит следующим образом:

new java.util.Timer().schedule(

    new java.util.TimerTask() {
        @Override
        public void run() {
            // your code here, and if you have to refresh UI put this code: 
           runOnUiThread(new   Runnable() {
                  public void run() {
                            //your code

                        }
                   });
        }
    }, 
    5000 
);

в вашем первоначальном вопросе упоминается "таймер качания". Если на самом деле ваш вопрос связан с SWing, то вы должны использовать таймер Swing, а не util.Таймер.

прочитайте раздел из учебника Swing на "как использовать таймеры" для получения дополнительной информации.

вы можете использовать нить.Sleep() функция

Thread.sleep(4000);
myfunction();

ваша функция будет выполнена через 4 секунды. Однако это может приостановить всю программу...

ScheduledThreadPoolExecutor имеет эту способность, но это довольно тяжелый вес.

Timer также имеет эту способность, но открывает несколько потоков, даже если используется только один раз.

вот простая реализация с тестом (подпись близко к Android обработчик.postDelayed()):

public class JavaUtil {
    public static void postDelayed(final Runnable runnable, final long delayMillis) {
        final long requested = System.currentTimeMillis();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        long leftToSleep = requested + delayMillis - System.currentTimeMillis();
                        if (leftToSleep > 0) {
                            Thread.sleep(leftToSleep);
                        }
                        break;
                    } catch (InterruptedException ignored) {
                    }
                }
                runnable.run();
            }
        }).start();
    }
}
Public static timer t;

public synchronized void startPollingTimer() {
        if (t == null) {
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                   //Do your work
                }
            };

            t = new Timer();
            t.scheduleAtFixedRate(task, 0, 1000);
        }
    }

как вариант ответа @tangens: если вы не можете дождаться, пока сборщик мусора очистит ваш поток, отмените таймер в конце вашего метода запуска.

    Timer t = new java.util.Timer()
    t.schedule( 
            new java.util.TimerTask() {
                @Override
                public void run() {
                    // your code here
                    // close the thread
                    t.cancel()
                }
            }, 
            5000 
    );

все остальные unswers требуют, чтобы запустить код внутри нового потока. В некоторых простых случаях использования вы можете просто немного подождать и продолжить выполнение в том же потоке/потоке.

код ниже демонстрирует эту технику. Имейте в виду, что это похоже на то, что Ява.утиль.Таймер делает под капотом, но более легкий.

import java.util.concurrent.TimeUnit;
public class DelaySample {
    public static void main(String[] args) {
       DelayUtil d = new DelayUtil();
       System.out.println("started:"+ new Date());
       d.delay(500);
       System.out.println("half second after:"+ new Date());
       d.delay(1, TimeUnit.MINUTES); 
       System.out.println("1 minute after:"+ new Date());
    }
}

DelayUtil Реализация

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class DelayUtil {
    /** 
    *  Delays the current thread execution. 
    *  The thread loses ownership of any monitors. 
    *  Quits immediately if the thread is interrupted
    *  
    * @param duration the time duration in milliseconds
    */
   public void delay(final long durationInMillis) {
      delay(durationInMillis, TimeUnit.MILLISECONDS);
   }

   /** 
    * @param duration the time duration in the given {@code sourceUnit}
    * @param unit
    */
    public void delay(final long duration, final TimeUnit unit) {
        long currentTime = System.currentTimeMillis();
        long deadline = currentTime+unit.toMillis(duration);
        ReentrantLock lock = new ReentrantLock();
        Condition waitCondition = lock.newCondition();

        while ((deadline-currentTime)>0) {
            try {
                lock.lockInterruptibly();    
                waitCondition.await(deadline-currentTime, TimeUnit.MILLISECONDS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            } finally {
                lock.unlock();
            }
            currentTime = System.currentTimeMillis();
        }
    }
}