2010-02-13 2 views
90

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

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

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

+0

Вы хотите подождать 5 секунд, а затем выполнить что-либо или продолжить выполнение чего-либо еще за 5 секунд? – whiskeysierra

+0

Я хочу продолжить делать что-то еще – ufk

ответ

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

EDIT:

javadoc говорит:

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

+1

Если вы запустите этот код, вы будете утечка потоков. Обязательно очистите таймер, когда закончите. – skaffman

+0

@skaffman: Я добавил заявление от javadoc. Вам действительно нужно очищать после расписания? – tangens

+0

Возможно, все в порядке, но может быть и так. Если вы запустите этот фрагмент кода несколько раз, у вас появятся свободные потоки, без возможности их убирать. – skaffman

39

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

// 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() немедленно прекратит пул потоков.

5

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

Thread.sleep(4000); 
myfunction(); 

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

+15

Это приостановит текущий поток, а не всю программу. – skaffman

+0

Да, конечно :) – dale

+0

И это только гарантирует, что исполнение будет выполняться после 4 секунд, что может означать и через 10 секунд! – questzen

3

В исходном вопросе упоминается «Качающийся таймер». Если на самом деле ваш вопрос связан с SWing, тогда вы должны использовать таймер Swing и NOT util.Timer.

Для получения дополнительной информации ознакомьтесь с разделом из учебника Swing на «How to Use Timers».

20

Пример использования 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 секунды).

Как упоминается в комментариях, вы должны найти «How to Use Swing Timers» для краткого введения.

5

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

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 
); 
1

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

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

Вот простая реализация с тестом (подпись близко к Handler.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(); 
    } 
} 

Тест:

@Test 
public void testRunsOnlyOnce() throws InterruptedException { 
    long delay = 100; 
    int num = 0; 
    final AtomicInteger numAtomic = new AtomicInteger(num); 
    JavaUtil.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      numAtomic.incrementAndGet(); 
     } 
    }, delay); 
    Assert.assertEquals(num, numAtomic.get()); 
    Thread.sleep(delay + 10); 
    Assert.assertEquals(num + 1, numAtomic.get()); 
    Thread.sleep(delay * 2); 
    Assert.assertEquals(num + 1, numAtomic.get()); 
} 
+0

он дает предупреждение сна, вызванный в цикле – shareef

1
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); 
     } 
    } 
+1

Хотя этот код может ответить на вопрос, предоставляя дополнительный контекст относительно того, почему и/или как этот код отвечает на вопрос, улучшает его долгосрочную ценность. – Mateus

0

В качестве варианта @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 
    ); 
Смежные вопросы