5

在我的服务器应用程序的某个时刻,我想停止一些正在执行 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);
        }
    }
}

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

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

要使这项技术发挥作用,任何捕获中断异常但不准备处理它的方法都必须立即重新声明该异常。我们说重新断言而不是重新抛出,因为并不总是可以重新抛出异常。如果捕获 InterruptedException 的方法未声明抛出此(已检查)异常,则应使用以下咒语“重新中断自身”: Thread.currentThread().interrupt();

谁能给我一些提示?一些代码示例将不胜感激。

4

2 回答 2

6

一个解决方案,由 Peter Lawrey 描述并且在这里也可以看到是关闭套接字。

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

调用 Thread 对象的中断方法会引发 InterruptedException,这甚至会停止阻塞 IO 操作。

于 2012-09-07T09:30:09.663 回答
6

您可以添加一个方法,如

public void close() throws IOException {
    this.socket.close();
}

并且任何阻塞的 IO 操作都会抛出一个 SocketException。

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

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

例如,您的读取可能只获得一个字节或获得一个数据包的结尾和另一个数据包的开头。

于 2012-09-07T09:17:37.587 回答