Java如何在程序关闭时停止线程

时间:2013-05-04 20:07:22

标签: java multithreading

我遇到了一些异常,我需要知道程序何时关闭,因为我需要关闭套接字。

我有默认的public static main方法,我不断重复一个动作和一个Thread类。

private static Thread thread;
public static boolean isRunning = true;  

public static void main(String[] args){

   thread = new Thread(new ThreadListenServer());
   thread.start();

   Timer timer = new Timer();
   TimerTask task = new TimerTask() {
      @Override
      public void run(){
         // some action
      }
   }

   timer.scheduleAtFixedRate(task, 0, 10000);

   isRunning = false;
}

在后台运行的线程类:

public class ThreadListenServer implements Runnable{

    private DatagramSocket socket;

    public ThreadListenServer() throws SocketException{
       socket = new DatagramSocket(6655);
    }

    @Override
    public void run() {

       while(MainProgram.isRunning){
            // some action
       }

       socket.close();
    }
}

我不知道为什么,但是isRunning它变得虚假,但它不应该。如果主程序关闭,我该如何关闭套接字? (这是因为即使程序关闭,线程仍然在后台运行)。

我正在考虑在主类中创建套接字,然后将套接字对象作为参数传递给ThreadClass,如果程序关闭,我也应该关闭套接字。

4 个答案:

答案 0 :(得分:4)

使用:

thread.setDaemon(true);

这将关闭线程。它告诉JVM它是一个后台线程,所以它会在退出时关闭。

答案 1 :(得分:2)

我假设你有一个类型的MainFrogram运行的JFrame。你有2个选择

1:设置Jframe在关闭时关闭所有线程。

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

2:添加一个窗口监听器并手动关闭你的线程(也许你必须在关闭它之前通过套接字发送一些信息)

addWindowListener(new WindowAdapter() {
  public void windowClosing(WindowEvent e) {
    // send your socket its close message and shut everything down
    System.exit(0);
  }
});

答案 2 :(得分:1)

有些事情会浮现在脑海中。

  1. 您似乎正在使用套接字执行阻止I / O操作。您可能需要中断正在运行的线程和/或套接字以使其停止阻止
  2. 您应该使用setDaemon(true)在启动之前将线程设置为守护程序线程。这将允许JVM自动终止线程......
  3. isRunning应标记为volatile,或者您应使用AtomicBoolean代替

答案 3 :(得分:1)

要在程序退出干净地时停止所有线程,您需要为每个启动的线程定义终止策略。这通常使用Interrupts完成,ExecutorService.shutdownNow()方法向每个正在运行的线程发送一个中断。

清洁终止政策包括两部分:

  • 向线程发送停止信号 - 也就是打断它
  • 设计线程以实现中断

通过调用Thread.interrupt()方法可以中断Java中的线程。线程可以通过调用Thread.isInterrupted()方法来检查中断。一个好的线程必须定期检查中断,例如作为循环条件并检查InterruptedExceptions的阻塞函数。

值得注意的是,Java中的Socket无法中断。例如,如果某个线程在Socket.accept()上被阻止,则当线程中断时它不会抛出InterruptedException。在这种情况下,您需要定义一个公共方法,通过调用Socket.close()来强制阻塞函数抛出异常(我猜SocketException)来关闭底层套接字。