在我的游戏中,我将实现一个函数,该函数可以在 5 秒内将变量的值从 100 线性更改为 0。该函数必须由玩家触摸按钮来启动。
首先,我想通过带有 TimeUnit.MILLISECONDS.sleep()
的 for
循环以及其中的值递减来完成此操作:
for (int i = 0; i <= 100; i++) {
decrementBatteryLevel();
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
但我很快发现这会导致我的整个游戏停止 5 秒,这不是我想要的。
因此,我实际尝试的第一件事是创建一个运行 for
循环的线程:
private Thread useBattery = new Thread(() -> {
for (int i = 0; i <= 100; i++) {
decrementBatteryLevel();
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
并在必要时调用它:
useBattery.start();
这有效,但仅限于第一次启动。第二次启动 useBattery
线程导致游戏抛出 java.lang.IllegalThreadStateException
。
我知道我无法启动已经存在的线程,所以我尝试这样做:
if (useBattery.isAlive()) {
useBattery.interrupt();
}
useBattery.start();
但是我最终再次抛出了java.lang.IllegalThreadStateException
。/* Thread 是一次性产品吗...? */
我尝试的最后一件事确实有效,那就是每次需要时创建一个新线程。这就是我目前拥有的:
new Thread(() -> {
for (int i = 0; i <= 100; i++) {
decrementBatteryLevel();
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
结果是令人满意的,但我担心这样做会很快用不必要的、“用完”的线程填满 RAM。有什么办法可以做得更好吗?
谢谢。
最佳答案
使用 ExecutorService
启动任务。
Executors.newSingleThreadExecutor();
然后,您可以提交
您的Runnable
或Callable
来获取相应的Future
。
final Future<?> submittedResult = executorService.submit(() -> { /* Your code */ });
启动新任务实例时,只需取消
并提交
submittedResult.cancel(true);
executorService.submit(() -> { /* Your code */ });
我认为您可以针对您的特定用例扩展我的答案。
另请参阅https://techblog.bozho.net/interrupting-executor-tasks/
关于java - 等待特定时间但不干扰应用程序的任何其他功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54638923/