2013-05-04 114 views
4

我得到一些異常,並且我需要知道程序何時關閉,因爲我需要關閉套接字。Java如何在程序關閉時停止線程

我有默認的公共靜態主要方法,我不斷重複一個動作和一個線程類。

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它變得假的,但它不應該。如果主程序關閉,我該如何關閉套接字? (這是因爲即使程序關閉,Thread仍然在後臺運行)。

我正在考慮在主類中創建套接字,然後將套接字對象作爲參數傳遞給ThreadClass,並且如果程序關閉了,我也應該關閉套接字。

+0

當你關閉一個進程時,它將關閉所有的資源,包括套接字。 – 2013-05-04 20:09:12

+0

由於您將其設置爲false,因此它變得不真實。 – 2013-05-04 20:10:21

+0

考慮使用執行程序而不是單獨的線程。完成後很容易重新獲得控制權。 – 2013-05-04 20:26:07

回答

1

想到幾件事情。

  1. 看來您正在使用套接字執行阻塞I/O操作。您可能需要中斷正在運行的線程和/或套接字以使其停止阻止
  2. 您應該使用setDaemon(true)將線程設置爲守護程序線程,然後才能啓動它。這將允許JVM自動終止線程...
  3. isRunning應標明volatile或者你應該使用AtomicBoolean代替
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); 
    } 
}); 
+0

只有當所有非守護進程線程都終止時,JVM纔會退出,這對OP問題沒有任何影響 – MadProgrammer 2013-05-04 20:57:42

+0

請查看[documentation](http://docs.oracle.com/javase/7/docs/ api/java/lang/Thread.html)更好的描述 – MadProgrammer 2013-05-04 21:04:27

+0

@MadProgrammer我知道守護進程線程,但由defualt線程不守護進程,我沒有看到OP設置它們是如此。還調用System.exit應該關閉所有這些線程。如果不是,那麼選項2仍然可行(並且是最好的IMO),將關閉消息發送到所有線程並關閉商店。 – 2013-05-04 21:12:48

4

用途:

thread.setDaemon(true); 

這將關閉該線程。它告訴JVM它是後臺線程,所以在退出時會關閉。

1

要停止所有線程當您的程序退出乾淨地,您需要爲每個開始的線程定義終止策略。這通常使用InterruptsExecutorService.shutdownNow()方法向每個正在運行的線程發送一箇中斷。

乾淨終止的政策包括兩個部分:

  • 發送停止信號線程 - 又名打斷它
  • 設計線程作用於中斷

Java中的線程可能被中斷通過調用Thread.interrupt()方法。線程可以通過調用Thread.isInterrupted()方法來檢查中斷。好的線程必須定期檢查中斷,例如,作爲循環條件並檢查InterruptedExceptions的阻止功能。

需要注意的是Socket S IN的Java漠視中斷是很重要的。例如,如果線程在Socket.accept()上被阻塞,當線程中斷時它不會拋出InterruptedException。在這種情況下,您需要定義一個公共方法,通過調用Socket.close()強制阻塞函數拋出異常(我猜SocketException)來關閉底層套接字。