我读了一些其他帖子,但没有找到我正在寻找的确切答案,所以我希望有人能给出一些澄清。
我有一个程序会运行一段时间。我有一些在后台运行的线程来执行各种任务,为了简单起见,让我们想想 3 个线程。
ThreadA
每 10 秒执行一次任务,其中 ThreadB
每 30 秒执行一次,而 ThreadC
每 5 分钟执行一次。
不使用busy waiting,指定时间让线程休眠
我的问题是关于干净关闭。我有一个变量,每个线程也有读取权限,所以他们可以看到用户何时启动程序退出。下次线程处于活动状态时,它们退出循环并加入,一切都很好。但是你可以看到 ThreadC 每 5 分钟才唤醒一次。
我的问题是我可以在休眠时间结束之前向休眠线程发出信号唤醒并退出吗?如果这不可能,我是否需要重新编写代码以使用
wait()
和 notify()
或者有更好的方法吗?
Thread.sleep
如果线程在睡眠期间被中断,则抛出 InterruptedException
。抓住它,检查你的旗帜。
如果线程正在使用
Thread.sleep(...)
休眠,您可以使用 Thread.interrupt()
唤醒它们。确保您正在处理 InterruptedException
并在循环中测试 Thread.currentThread().isInterrupted()
。
您可以在您的线程上调用
interrupt()
方法,这将使您的线程从running state
转到block state
,但它会抛出一个异常InterruptedException
,到那时您可以在catch
中关闭您的线程
块
还有其他解决方案是您可以使用定时器任务,它将在您指定的特定时间调用运行方法,而无需将您的线程放入
block state
例子:
public class TimerBomb {
Toolkit toolkit;
Timer timer;
int count = 0;
public TimerBomb(int seconds) {
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new RemindTask(), seconds * 1000, seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
//do stuff here
}
}
public static void main(String args[]) {
System.out.println("About to schedule task.");
Thread t = new Thread(new Runnable() {
@Override
public void run() {
new TimerBomb(5);
}
});
t.start();
System.out.println("Task scheduled.");
}
}
它将永远每 5 秒运行一次。
您应该查看 ExecutorService 及其 shutdownNow() 方法(通常会中断所有活动线程)。你感觉重新发明了调度轮。
所有其他答案都是您实际提出的问题的良好答案,但没有一个给出您应该提出的问题的最佳答案。问题是,安排几个必须在不同时期重复出现的周期性任务的最佳方法是什么?答案是,使用 java.util.concurrent.ScheduledExecutorService。
像所有 ExeuctorServices 一样,它提供了方法,shutdown() 和 shutdownNow(),用于您希望任务停止的时间。
您将如何区分执行操作或关闭线程?设置一个动作代码到线程和中断线程不是原子的。在这两个动作之间可能会从系统中引发一个额外的中断,并且此信息将丢失,因为线程只看到中断后的动作代码,但不关心发生了多少中断。
所以,我认为线程中断只能用于优雅地完成一个线程。