【问题标题】:Interrupting thread which is blocked waiting on IO from socket?中断阻塞等待来自套接字的IO的线程?
【发布时间】:2023-10-24 20:14:01
【问题描述】:

我有一个应用程序可以侦听指定主机名和端口上的传入连接。使用listen()(见下文)方法调用监听,该方法不断等待使用ServerSocket.accept() 的传入连接,创建一个新的Thread 来处理输入流。

private ServerSocket serverSocket;
private Thread listenerThread;

public void listen() throws IOException {
    this.listenerThread = new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                try {
                    Socket socket = TheServerClass.this.serverSocket.accept();
                    // Create new thread to handle the incoming connection
                }
                catch (IOException exc) { }
            }
        }
    });
    this.listenerThread.start();
}

现在我想停止运行listenerThread。但是当我打电话给this.listenerThread.interrupt() 时,这不起作用。
我以为你可以通过中断线程来停止它,那为什么不起作用呢?

注意:一种可能的解决方案是使用this.serverSocket.close() 关闭ServerSocket,但可以使用interrupt() 或其他方式来完成吗?)

【问题讨论】:

  • 正如您所指出的,当使用标准套接字时,这只能通过关闭套接字来实现。这里有几个关于 SO 处理相同问题的问题,例如*.com/questions/1510403/…
  • 它不起作用是什么意思?它会抛出任何异常吗?还是通常继续?
  • @medopal 线程只是继续运行而不终止它。

标签: java multithreading serversocket


【解决方案1】:

致电serverSocket.close()

我猜因为你还没有做 IO - 你不能中断它,因为accept() 没有抛出 InterruptedException 你将无法中断它。线程被中断了,但是你必须自己检查那个标志Thread.isInterrupted()

How can I interrupt a ServerSocket accept() method?

【讨论】:

  • 既然accept()不能被打断(在我看来这有点奇怪,但就这样吧),我想我必须使用close()...谢谢你的帮助!
【解决方案2】:

答案就在问题中。您需要关闭套接字。使用serverSocket.close() 完成。 Thread.interrupt() 不关心套接字。

【讨论】:

    【解决方案3】:

    使用这个:

    public class MyThread extends Thread {
    
        private boolean stop;
        private ServerSocket serverSocket;
    
        public MyThread(ServerSocket ss) {
            this.serverSocket = ss;
            this.stop = false;
        }
    
        public void setStop() {
            this.stop = true;
            if (this.ss != null) {
                this.ss.close();
            }
        }
    
        public void run() {
            while (!stop) {
                try {
                    Socket socket = serverSocket.accept();
                    // Create new thread to handle the incoming connection 
                }
                catch (IOException exc) { }
            }
        }
    }
    

    listen() 方法调用线程的setStop() 方法。

    【讨论】:

    • 不好。您至少应该将stop 声明为 volatile,否则编译器可能会以这种方式对其进行优化,不同的线程会看到不同的值。
    最近更新 更多