У мене є певна функція, яку я хочу виконати через 5 секунд. Як я можу це зробити на Java?
Я знайшов javax.swing.timer, але я не можу зрозуміти, як ним користуватися. Схоже, я шукаю щось простіше, ніж цей клас.
Додайте простий приклад використання.
У мене є певна функція, яку я хочу виконати через 5 секунд. Як я можу це зробити на Java?
Я знайшов javax.swing.timer, але я не можу зрозуміти, як ним користуватися. Схоже, я шукаю щось простіше, ніж цей клас.
Додайте простий приклад використання.
Відповіді:
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here
}
},
5000
);
Редагувати:
javadoc каже:
Після того, як остання посилання на об'єкт «Таймер» в реальному часі закінчується, і всі невиконані завдання завершено, потік виконання завдання таймера граціозно припиняється (і стає предметом збирання сміття). Однак це може тривати довільно довго.
import java.util.Timer; import java.util.TimerTask;
може зробити більш очевидним, що це не так javax.swing.Timer
. / Зауважте, якщо ви використовуєте Swing (а насправді AWT), ви не повинні нічого робити для зміни компонентів у потоках відправки Discatch Thread (EDT) без подій ( java.util.Timer
завдання погані; javax.swing.Timer
дії хороші).
cancel
методом docs - виклик таймера в кінці методу запуску очистить порядок виконання програми TimerTasks.
Щось на зразок цього:
// 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
);
Як варіант відповіді @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
);
Timer t
слід задекларувати, final
оскільки це доступ до внутрішнього класу?
У вашому оригінальному запитанні згадується "Таймер гойдалки". Якщо насправді ваше питання пов'язане з SWing, то вам слід скористатися таймером Swing, а НЕ util.Timer.
Прочитайте розділ підручника Swing на тему " Як користуватися таймерами " для отримання додаткової інформації.
ви можете використовувати функцію Thread.Sleep ()
Thread.sleep(4000);
myfunction();
Ваша функція буде виконуватися через 4 секунди. Однак це може призупинити всю програму ...
ScheduledThreadPoolExecutor
має цю здатність, але це досить важка вага.
Timer
також має цю здатність, але відкриває кілька потоків, навіть якщо використовується лише один раз.
Ось проста реалізація з тестом (підпис близький до Android 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() {
// The while is just to ignore interruption.
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());
}
while
просто ігнорувати переривання.
Усі інші відмовники потребують запуску коду в новій темі. У деяких простих випадках використання ви можете просто зачекати трохи і продовжити виконання в межах однієї теми / потоку.
Кодекс нижче демонструє цю техніку. Майте на увазі, це схоже на те, що робить java.util.Timer під капотом, але більш легкий.
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();
}
}
}
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);
}
}