您可以尝试将线程设置为守护程序模式。您可以使用 Thread 中的 setDaemon() 方法来执行此操作。当唯一运行的线程都是守护线程时,Java 虚拟机退出。您创建的线程可能是用户线程,因此 JVM 不会退出。
http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setDaemon(boolean)
我确实有没有明确执行此操作的软件,但我没有这个问题,因此您的线程可能不知道它们应该停止运行。您可以通过使用某种控制标志来解决此问题,让您的线程知道它们现在可以停止。使用 AtomicBoolean 可以很好地解决这个问题。如果您使用的是 Tomcat,您可以创建一个 servlet 作为您的主根来启动和控制您的线程。Tomcat 承诺在关闭时运行您的 servlet 的 destroy() 方法,这可以正确地停止您的线程运行。这是一个基本的例子。
@WebServlet(urlPatterns = {"/checkStatus"}, loadOnStartup = 1)
public class ThreadController extends HttpServlet {
private AtomicBoolean running = new AtomicBoolean(false);
private Thread myThread = new Thread() {
@Override
public void run() {
while (running.get()) {
//do stuff
}
}
};
@Override
public void destroy() {
running.set(false);
myThread.interrupt();
}
@Override
public void init() throws ServletException {
running.set(true);
myThread.start();
}
}
虽然在我的实现中我使用 Executors 来启动和中断我的线程,但您可以自己进一步查看。
另一种选择是使用 ScheduledExecutorService。
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> cleanUpHandle;
@Override
public void init() {
cleanUpHandle = scheduler.scheduleAtFixedRate(cleanUp, 60, 60, TimeUnit.SECONDS);
}
@Override
public void destroy() {
cleanUpHandle.cancel(true);
}
在我上面的示例中,cleanUp 是一个 Thread 实现。使用调度程序的好处是您不需要在线程的 run 方法中控制 while 循环。run 方法只对其任务进行一次迭代并完成。
这些只是您可以尝试的一些事情,正确的解决方案将基于您要完成的任务。