【发布时间】:2014-12-06 08:01:45
【问题描述】:
我需要实现一个在单击按钮 60 秒后运行的函数。请帮忙,我使用了 Timer 类,但我认为这不是最好的方法。
【问题讨论】:
标签: java javascript timer settimeout setinterval
我需要实现一个在单击按钮 60 秒后运行的函数。请帮忙,我使用了 Timer 类,但我认为这不是最好的方法。
【问题讨论】:
标签: java javascript timer settimeout setinterval
underscore-java 库中有setTimeout() 方法。
代码示例:
import com.github.underscore.Underscore;
import java.util.function.Supplier;
public class Main {
public static void main(String[] args) {
final Integer[] counter = new Integer[] {0};
Supplier<Void> incr =
() -> {
counter[0]++;
return null;
};
Underscore.setTimeout(incr, 0);
}
}
该函数将在 100 毫秒内启动一个新线程。
【讨论】:
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// here goes your code to delay
}
}, 300L); // 300 is the delay in millis
Here你可以找到一些信息和例子。
【讨论】:
Timer timer = new Timer(); timer.schedule(...); timer.cancel();
使用 Java 9 CompletableFuture,一切都很简单:
CompletableFuture.delayedExecutor(5, TimeUnit.SECONDS).execute(() -> {
// Your code here executes after 5 seconds!
});
【讨论】:
“我使用了 Timer 类,但我认为这不是最好的方法。”
其他答案假设您没有使用 Swing 作为您的用户界面(按钮)。
如果您使用的是 Swing,请不要使用Thread.sleep(),因为它会冻结您的 Swing 应用程序。
您应该使用javax.swing.Timer。
有关更多信息和示例,请参阅 Java 教程 How to Use Swing Timers 和 Lesson: Concurrency in Swing。
【讨论】:
delayedExecutor的答案
public ScheduledExecutorService = ses;
ses.scheduleAtFixedRate(new Runnable(){
run(){
//running after specified time
}
}, 60, TimeUnit.SECONDS);
它在 scheduleAtFixedRate 60 秒后运行 https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html
【讨论】:
不要使用Thread.sleep,否则它会冻结你的主线程并且不会从 JS 模拟 setTimeout。您需要创建并启动一个新的后台线程来运行您的代码,而无需停止主线程的执行。像这样:
new Thread() {
@Override
public void run() {
try {
this.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// your code here
}
}.start();
【讨论】:
使用JDK 1.8的异步实现:
public static void setTimeout(Runnable runnable, int delay){
new Thread(() -> {
try {
Thread.sleep(delay);
runnable.run();
}
catch (Exception e){
System.err.println(e);
}
}).start();
}
使用 lambda 表达式调用:
setTimeout(() -> System.out.println("test"), 1000);
或者有方法参考:
setTimeout(anInstance::aMethod, 1000);
处理当前运行的线程只使用同步版本:
public static void setTimeoutSync(Runnable runnable, int delay) {
try {
Thread.sleep(delay);
runnable.run();
}
catch (Exception e){
System.err.println(e);
}
}
在主线程中谨慎使用它——它会在调用之后暂停所有内容,直到 timeout 到期并且 runnable 执行。
【讨论】:
class 也启动了“线程过多”:“一种线程安排任务以供将来在后台线程中执行的工具。”我认为这种方式实际上很干净。它不处理重复执行的情况,但你总是可以让你的任务在最后再次调用 settimeout。
您可以简单地使用Thread.sleep() 来实现此目的。但是,如果您在具有用户界面的多线程环境中工作,您可能希望在单独的线程中执行此操作,以避免睡眠阻塞用户界面。
try{
Thread.sleep(60000);
// Then do something meaningful...
}catch(InterruptedException e){
e.printStackTrace();
}
【讨论】:
您应该使用Thread.sleep() 方法。
try {
Thread.sleep(60000);
callTheFunctionYouWantTo();
} catch(InterruptedException ex) {
}
这将等待 60,000 毫秒(60 秒),然后执行代码中的下一条语句。
【讨论】: