具有套接字I/O阻塞操作的中断/停止线程

amp*_*amp 5 java sockets multithreading

在我的服务器应用程序的某些时候,我想停止一些执行I/O阻塞操作的线程.

例如,其中一个有以下run()方法:

public void run() {
    System.out.println("GWsocket thread running");

    int len;
    byte [] buffer = new byte[1500];
    try {
        this.in  = new DataInputStream(this.socket.getInputStream());
        this.out = new DataOutputStream(this.socket.getOutputStream());
        running = true;

        while (running){
            len = in.read (buffer);
            if (len < 0)
                running = false;
            else
                parsepacket (buffer, len);
        }

    }catch (IOException ex) {
        System.out.println("GWsocket catch IOException: "+ex);
    }finally{
        try {
            System.out.println("Closing GWsocket");
            fireSocketClosure();
            in.close();
            out.close();
            socket.close();
        }catch (IOException ex) {
            System.out.println("GWsocket finally IOException: "+ex);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我想停止运行此代码的线程,我该怎么办?

这里他们展示了如何做(如何停止等待很长时间的线程(例如,输入)?),但我不明白他们的意思:

要使此技术起作用,任何捕获中断异常并且不准备立即处理它的方法都必须重新确认异常.我们说重申而不是重新抛出,因为并不总是可以重新抛出异常.如果没有声明捕获InterruptedException的方法抛出此(已检查)异常,那么它应该使用以下咒语"重新中断":Thread.currentThread().interrupt();

任何人都可以给我一些提示吗?一些代码示例将非常感激.

Pet*_*rey 6

您可以添加类似的方法

public void close() throws IOException {
    this.socket.close();
}
Run Code Online (Sandbox Code Playgroud)

并且任何阻塞IO操作都将抛出SocketException.

您可能希望设置一个标志closed,您可以检查是否预期抛出异常.

顺便说一句:你不能确定你会在读取时获得离散数据包.阅读所需内容并使用BufferedInputStream提高效率要好得多.如果您不需要解析内容,只读取块,例如从套接字复制到文件.

例如,您的读取只能获得一个字节或获得一个数据包的结束和另一个数据包的开始.


Den*_*ret 6

Peter Lawrey描述的解决方案也在这里看到是关闭套接字.

使用nio,您还可以使用可中断SocketChannel,并允许应用Java标准中断模型.

调用Thread对象的interrupt方法会抛出InterruptedException,甚至会阻止阻塞IO操作.