等待特定时间但不干扰应用程序的任何其他功能

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 您的 RunnableCallable 获得相应的 Future.

final Future<?> submittedResult = executorService.submit(() -> { /* Your code */ });

启动新任务实例时,只需cancelsubmit

submittedResult.cancel(true);
executorService.submit(() -> { /* Your code */ });

我认为您可以针对您的特定用例扩展我的答案。
另请参阅 https://techblog.bozho.net/interrupting-executor-tasks/