等待特定时间但不干扰应用程序的任何其他功能
Wait a specific amount of time but not disturb any other function of the application
在我的游戏中,我将实现一个函数,将变量的值从 100 线性更改为 0 5 秒。该函数必须由玩家触摸按钮启动。
首先,我想通过一个 for
循环和 TimeUnit.MILLISECONDS.sleep()
以及其中的值递减来完成它:
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();
结果令人满意,但我担心这样做会很快用不必要的 "used up" 线程填满 RAM。有什么办法可以做得更好吗?
谢谢。
使用 ExecutorService
启动任务。
Executors.newSingleThreadExecutor();
然后您可以 submit
您的 Runnable
或 Callable
获得相应的 Future
.
final Future<?> submittedResult = executorService.submit(() -> { /* Your code */ });
启动新任务实例时,只需cancel
和submit
submittedResult.cancel(true);
executorService.submit(() -> { /* Your code */ });
我认为您可以针对您的特定用例扩展我的答案。
另请参阅 https://techblog.bozho.net/interrupting-executor-tasks/
在我的游戏中,我将实现一个函数,将变量的值从 100 线性更改为 0 5 秒。该函数必须由玩家触摸按钮启动。
首先,我想通过一个 for
循环和 TimeUnit.MILLISECONDS.sleep()
以及其中的值递减来完成它:
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();
结果令人满意,但我担心这样做会很快用不必要的 "used up" 线程填满 RAM。有什么办法可以做得更好吗?
谢谢。
使用 ExecutorService
启动任务。
Executors.newSingleThreadExecutor();
然后您可以 submit
您的 Runnable
或 Callable
获得相应的 Future
.
final Future<?> submittedResult = executorService.submit(() -> { /* Your code */ });
启动新任务实例时,只需cancel
和submit
submittedResult.cancel(true);
executorService.submit(() -> { /* Your code */ });
我认为您可以针对您的特定用例扩展我的答案。
另请参阅 https://techblog.bozho.net/interrupting-executor-tasks/