java:在特定秒数后运行一个函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2258066/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java: run a function after a specific number of seconds
提问by ufk
I have a specific function that I want to be executed after 5 seconds. How can i do that in Java?
我有一个特定的功能,我想在 5 秒后执行。我如何在 Java 中做到这一点?
I found javax.swing.timer, but I can't really understand how to use it. It looks like I'm looking for something way simpler then this class provides.
我找到了 javax.swing.timer,但我真的不明白如何使用它。看起来我正在寻找比这个类提供的更简单的方法。
Please add a simple usage example.
请添加一个简单的使用示例。
采纳答案by tangens
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here
}
},
5000
);
EDIT:
编辑:
javadocsays:
javadoc说:
After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection). However, this can take arbitrarily long to occur.
在对 Timer 对象的最后一个实时引用消失并且所有未完成的任务都已完成执行后,计时器的任务执行线程将正常终止(并成为垃圾收集的对象)。但是,这可能需要任意长的时间才能发生。
回答by skaffman
Something like this:
像这样的东西:
// 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();
There are various other factory methods on Executor
which you can use instead, if you want more threads in the pool.
Executor
如果您希望池中有更多线程,您可以使用其他各种工厂方法。
And remember, it's important to shutdown the executor when you've finished. The shutdown()
method will cleanly shut down the thread pool when the last task has completed, and will block until this happens. shutdownNow()
will terminate the thread pool immediately.
请记住,完成后关闭执行程序很重要。shutdown()
当最后一个任务完成时,该方法将干净地关闭线程池,并会阻塞直到发生这种情况。shutdownNow()
将立即终止线程池。
回答by dale
you could use the Thread.Sleep() function
你可以使用 Thread.Sleep() 函数
Thread.sleep(4000);
myfunction();
Your function will execute after 4 seconds. However this might pause the entire program...
您的函数将在 4 秒后执行。但是这可能会暂停整个程序......
回答by camickr
Your original question mentions the "Swing Timer". If in fact your question is related to SWing, then you should be using the Swing Timer and NOT the util.Timer.
您最初的问题提到了“摇摆计时器”。如果实际上您的问题与 SWing 有关,那么您应该使用 Swing Timer 而不是 util.Timer。
Read the section from the Swing tutorial on "How to Use Timers" for more information.
回答by zpon
Example of using javax.swing.Timer
使用示例 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!
This code will only be executed once, and the execution happens in 3000 ms (3 seconds).
这段代码只会执行一次,执行时间为 3000 毫秒(3 秒)。
As camickr mentions, you should lookup "How to Use Swing Timers" for a short introduction.
正如 camickr 所提到的,您应该查找“ How to Use Swing Timers”以获得简短的介绍。
回答by user2885850
My code is as follows:
我的代码如下:
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
);
回答by AlikElzin-kilaka
ScheduledThreadPoolExecutor
has this ability, but it's quite heavyweight.
ScheduledThreadPoolExecutor
有这个能力,但是相当的重量级。
Timer
also has this ability but opens several thread even if used only once.
Timer
也有这个能力,但即使只使用一次也会打开多个线程。
Here's a simple implementation with a test (signature close to Android's Handler.postDelayed()):
这是一个带有测试的简单实现(签名接近 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() {
while (true) {
try {
long leftToSleep = requested + delayMillis - System.currentTimeMillis();
if (leftToSleep > 0) {
Thread.sleep(leftToSleep);
}
break;
} catch (InterruptedException ignored) {
}
}
runnable.run();
}
}).start();
}
}
Test:
测试:
@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());
}
回答by Amol K
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);
}
}
回答by Dandalf
As a variation of @tangens answer: if you can't wait for the garbage collector to clean up your thread, cancel the timer at the end of your run method.
作为@tangens 答案的变体:如果您不能等待垃圾收集器清理您的线程,请在 run 方法结束时取消计时器。
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
);
回答by Valchkou
All other unswers require to run your code inside a new thread. In some simple use cases you may just want to wait a bit and continue execution within the same thread/flow.
所有其他 unswers 都需要在新线程中运行您的代码。在一些简单的用例中,您可能只想稍等片刻并在同一线程/流中继续执行。
Code below demonstrates that technique. Keep in mind this is similar to what java.util.Timer does under the hood but more lightweight.
下面的代码演示了该技术。请记住,这类似于 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 Implementation
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();
}
}
}