簡體   English   中英

終止應用程序和ScheduledExecutorService; 線

[英]Terminating application and ScheduledExecutorService; Thread

我有以下邏輯(簡化):

public class Application {

    public static volatile boolean stopServer;
    private static ScheduledExecutorService taskScheduler;

    private static Thread listenerThread;

    public static synchronized void switchStopServer() {
        stopServer = true;

        listenerThread.interrupt();
        taskScheduler.shutdownNow();
    }

    public static void main(String[] args) {
            int threadPoolSize = 4;
            taskScheduler = Executors.newScheduledThreadPool(threadPoolSize);

            listenerThread = new ListenerThread();
            taskScheduler.schedule(listenerThread, 0, TimeUnit.NANOSECONDS);
    }

}

public class ListenerThread extends Thread {

    private static ServerSocket serverSocket;
    private Socket socketConnection;

    @Override
    public void run() {
         while (!Application.stopServer) {
              try {
                   socketConnection = serverSocket.accept();
                   new CommunicatorThread(socketConnection).start();
              } catch (SocketException e) {
              } catch (Exception e) {
              }
         }  
    }

    private static void closeServerSocket() {
         try {
              if (serverSocket != null && !serverSocket.isClosed()) serverSocket.close();
         } catch (Exception e) { }
    }

    @Override
    public void interrupt() {
         closeServerSocket();
         super.interrupt();
    }

}

我想要實現的是以正確的方式終止Thread 首先,這是( switchStopServer() )正確的方法,還是有更好的解決方案?

我對ScheduledExecutorService有點困惑,因為shutdownNow()不會中斷Thread s, ScheduledFuture.cancel(true)也沒有(至少對我來說它沒有),所以我不能打斷ServerSocket.accept() 我知道,在我的例子中,不需要ScheduledExecutorService ,但在我的實際應用程序中有。

我相信你的問題是你在混淆ThreadRunnable 即使ListenerThread擴展了Thread ,它實際上也不是它自己的線程。 該線程由ExecutorService線程池管理,該線程池只調用run()方法。 這只是[有點]工作,因為Thread也實現了Runnable 當你調用ListenerThread.interrupt()你不是在打斷線程池中的線程,盡管你正在調用你的interrupt()方法而只是直接在調用線程中。 這應該關閉套接字,因為它從外部調用closeServerSocket()

當您調用ScheduledFuture.cancel(true)shutdownNow() ,應該中斷線程,但這不會調用您的interrupt()方法。 您可以在run()方法中使用Thread.currentThread().isInterrupted()來測試中斷。

您應該從擴展Thread更改ListenerThread ,而是讓它只實現Runnable請參閱下面的編輯 )。 您將需要在run()方法中執行類似以下循環的操作:

while (!Application.stopServer && !Thread.currentThread().isInterrupted()) {

要中斷accept()方法,您將不得不從另一個線程關閉serverSocket 這很可能是由調用interrupt()的線程完成的。 它應該關閉套接字, shutdownNow()cancel()線程池,然后它可以等待池終止。

編輯:

實際上,我想知道你為什么要為ListenerThread使用一個池,因為它只會有一個,它會被立即調度,它只是直接在任何連接上啟動一個新線程。 我會完全刪除你的taskScheduler池,讓ListenerThread繼續擴展Thread ,然后只調用new ListenerThread().start();

外部線程仍然只是關閉serverSocket以停止ListenerThread 如果你還需要關閉所有連接,那么ListenerThread需要保留socketConnection的集合,這樣當accept()拋出IOException時它可以調用它們的close()

另外,目前你有private Socket socketConnection; 這是誤導性的,因為它會在每次調用accept()后發生變化。 我把它重寫為:

 Socket socketConnection = serverSocket.accept();
 new CommunicatorThread(socketConnection).start();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM