簡體   English   中英

如何解除阻塞在ServerSocket.accept()上阻塞的線程?

[英]How to unblock a thread blocked on ServerSocket.accept()?

我有一個服務器線程與此代碼:

public void run() {
    try {
        ServerSocket server;
        EneaLog.printLog("Server is running.");
        server = new ServerSocket(this.portnumber);

        while (true) {
            new EneaServerConnection(server.accept(), this.project,stopped).start();
            if (stopped) {
                EneaLog.printLog("Server safe-shutdown completed.");
                EneaLog.printLog("Hi!");
                server.close();
                return;
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(EneaServer.class.getName()).log(Level.SEVERE, null, ex);
        project.getExceptionHandler().handler(ex);
    }
}

和這樣的關機方法:

public void shutdown() {
    EneaLog.printLog("Server shutdown NOW!");
    stopped = true;
}

我希望關閉可以解除在server.accept()上等待的線程,否則我必須在服務器關閉之前等待連接。

我不能在shutdown()中執行server.close()因為我必須向注冊客戶端發信號通知服務器正在關閉。

有任何想法嗎?

我嘗試設計我的代碼,以便它可以通過中斷“關閉”。 主要是因為Java的並Executor中的Executor框架使用interrupt來取消正在運行的任務。 此外,“關閉”任務不必知道正在被殺死的任務的任何內部。

但是,對accept的調用不會響應中斷, 除非它是ServerSocketChannel創建的。 使用ServerSocket構造函數創建的服務器將忽略中斷,我還沒有找到重新配置它的方法。

如果您無法更改創建服務器的代碼,請安排另一個線程在服務器套接字上調用close 無論用於創建服務器套接字的方法如何,這也會在accept阻塞的線程中引發異常。

使用SSL時,這是一個非常大的痛苦。 JSSE套接字不是從InterruptibleChannel創建的,並且不會響應線程上的簡單中斷。


我只是注意到問題是在沒有通知客戶端的情況下無法關閉服務器。 成功中斷套接字會導致其關閉。

accept此調用的調用應該不是問題,因為如果服務器套接字在accept中被阻止,則客戶端未連接。 這應該只是Socket實例的一個問題,它代表當前的連接。

如果這不滿足通知要求,則可能需要在非阻塞模式下使用NIO的ServerSocketChannel進行返工。

您應該能夠從另一個線程關閉套接字。

中斷(這取決於中斷點以相同的方式取消取決於取消點)也不會關閉(接受不響應關閉其文件描述符)。 您必須與accept進行通信(嘗試sendto,並發出關閉通知)以通知它不繼續接受。 至少在linux上就是這種情況; 不知道在其他平台上是什么樣的。

我一直面臨着同樣的問題。 我的工作解決方案包括關閉ServerSocket對象(serverSocket.close()); 這樣做會導致accept()方法拋出SocketException,這是你想要做的。

文森特

你試過Thread.interrupt()嗎?

如果此線程在可中斷通道上的I / O操作中被阻塞,則通道將關閉,線程的中斷狀態將被設置,並且線程將收到ClosedByInterruptException。

如果此線程在Selector中被阻塞,則線程的中斷狀態將被設置,並且它將立即從選擇操作返回,可能具有非零值,就像調用選擇器的喚醒方法一樣。

暫無
暫無

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

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