【发布时间】:2023-06-19 11:15:02
【问题描述】:
在代码中,变量 timer 将指定结束 while 循环的持续时间,例如 60 秒。
while(timer) {
//run
//terminate after 60 sec
}
【问题讨论】:
-
似乎我们在这里重新整理了一个旧线程:*.com/questions/2550536/…
在代码中,变量 timer 将指定结束 while 循环的持续时间,例如 60 秒。
while(timer) {
//run
//terminate after 60 sec
}
【问题讨论】:
long start = System.currentTimeMillis();
long end = start + 60*1000; // 60 seconds * 1000 ms/sec
while (System.currentTimeMillis() < end)
{
// run
}
【讨论】:
start 和 end 是绝对时间,以自纪元(UTC 1970 年 1 月 1 日午夜)以来的毫秒数为单位。没有翻转。
您应该尝试新的 Java 执行器服务。 http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
有了这个,你就不需要自己编程循环来测量时间了。
public class Starter {
public static void main(final String[] args) {
final ExecutorService service = Executors.newSingleThreadExecutor();
try {
final Future<Object> f = service.submit(() -> {
// Do you long running calculation here
Thread.sleep(1337); // Simulate some delay
return "42";
});
System.out.println(f.get(1, TimeUnit.SECONDS));
} catch (final TimeoutException e) {
System.err.println("Calculation took to long");
} catch (final Exception e) {
throw new RuntimeException(e);
} finally {
service.shutdown();
}
}
}
【讨论】:
Thread.sleep(1337);?
如果你不能超过你的时间限制(这是一个硬限制),那么线程是你最好的选择。达到时间阈值后,您可以使用循环终止线程。当时该线程中发生的任何事情都可以被中断,从而使计算几乎立即停止。这是一个例子:
Thread t = new Thread(myRunnable); // myRunnable does your calculations
long startTime = System.currentTimeMillis();
long endTime = startTime + 60000L;
t.start(); // Kick off calculations
while (System.currentTimeMillis() < endTime) {
// Still within time theshold, wait a little longer
try {
Thread.sleep(500L); // Sleep 1/2 second
} catch (InterruptedException e) {
// Someone woke us up during sleep, that's OK
}
}
t.interrupt(); // Tell the thread to stop
t.join(); // Wait for the thread to cleanup and finish
这将使您的分辨率约为 1/2 秒。通过在 while 循环中更频繁地进行轮询,您可以将其降低。
你的 runnable 的运行看起来像这样:
public void run() {
while (true) {
try {
// Long running work
calculateMassOfUniverse();
} catch (InterruptedException e) {
// We were signaled, clean things up
cleanupStuff();
break; // Leave the loop, thread will exit
}
}
根据 Dmitri 的回答更新
Dmitri 指出TimerTask,它可以让你避免循环。您可以只进行加入调用,而您设置的 TimerTask 将负责中断线程。这将使您无需循环轮询即可获得更精确的分辨率。
【讨论】:
.interrupt() 的工作原理。除非线程被阻塞,它只是设置interrupted 标志,线程仍然必须检查它以停止执行。另外,InterruptedException 是一个检查异常,你不能随便乱扔一些任意代码(你的例子不会编译)。
取决于 while 循环在做什么。如果有可能会阻塞很长时间,请使用TimerTask 安排任务来设置stopExecution 标志,以及.interrupt() 你的线程。
在循环中只有一个时间条件,它可以永远坐在那里等待输入或锁定(再说一遍,对你来说可能不是问题)。
【讨论】: