4

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

我有默认的公共静态 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

4 回答 4

4

利用:

thread.setDaemon(true);

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

于 2013-05-04T22:54:43.417 回答
2

我假设您有一个作为 MainProgram 类运行的某种 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);
  }
});
于 2013-05-04T20:55:02.543 回答
1

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

干净的终止策略由两部分组成:

  • 向线程发送停止信号——也就是中断它
  • 设计线程以应对中断

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

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

于 2013-05-13T00:05:24.377 回答
1

有几件事浮现在脑海。

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