线程在Java中完成时关闭资源

时间:2013-10-15 20:40:27

标签: java multithreading sockets

我有一个使用网络端口进行通信的线程。我补充道 cancel()方法停止执行并关闭网络资源(How to properly stop the Thread in Java?

private class ServerThread extends Thread {
        int portNumber;
        String serverAddress = null;

        public ServerThread(String serverAddress, int portNumber) {
            super();
            this.serverAddress = "localhost";
            this.portNumber = portNumber;
        }

        @Override
        public void run() {
            ServerSocket listener;
            Socket socket;
            try {
                listener = new ServerSocket(this.portNumber);
                socket = listener.accept();
                BufferedReader in = new BufferedReader(new InputStreamReader(
                        socket.getInputStream()));
                PrintWriter out = new PrintWriter(socket.getOutputStream(),
                        true);

                while (!isInterrupted()) {
                    String input = in.readLine();
                    if (input != null) {
                        out.println(input);
                        System.out.println("Hi:" + input);
                    }
                } // end of while loop
                System.out.println("OUT"); <-- ???
                socket.close(); <-- ???
                listener.close(); <-- ???
            } catch (IOException e) {
                e.printStackTrace();
            } 
        }

        public void cancel() {
            System.out.println("cancel called");
            interrupt();
        }
    }

问题在于,当我执行ServerThread并发送cancel()消息来完成执行时,似乎三行代码从未执行过:System.out.println("OUT"); socket.close(); listener.close();

似乎我不需要发送cancel()消息来完成线程。

ServerThread s = new ServerThread(serverAddress, serverPortNumber);
s.start();
...
s.cancel(); // ???

关闭线程使用资源的推荐方法是什么? 不再使用线程时,我不必关闭资源吗?或者一切都只是自动处理?

ADDED

似乎该线程被自动杀死,因为此代码正常工作。

            while(true) {
                String input = in.readLine();

                if (input != null) {
                    System.out.println("Received:" + input);
                    out.println(input);
                }
            } // end of while loop
            /* System.out.println("OUT");
            socket.close();
            listener.close(); */

2 个答案:

答案 0 :(得分:1)

Thread#interrupt()不会中断套接字上的阻塞I / O调用。尝试设置一个“stop”标志并在cancel()方法中关闭套接字,然后处理异常并检查while循环中的标志。

InterruptibleChannel对中断调用作出反应,但不是“老式”套接字流。

答案 1 :(得分:1)

在Java 7中,您可以使用try (resource) {} catch这样的习语:

try (final BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
  while ((line = reader.readLine()) != null) {
    process(line);
  }
} catch (IOException e) {
  e.printStackTrace();
}

这将保证在尝试块离开后正确关闭流。无论内部发生什么或try / catch如何终止。