用流关闭一个套接字

时间:2015-08-10 23:44:13

标签: java sockets garbage-collection

我的以下问题非常简单。

这是我的代码:

public class Protocol implements Runnable {

    private SSLSocket socket = null;
    private InputStream is = null;
    private OutputStream os = null;

    ...

    public Protocol(Socket s) {
        socket = (SSLSocket)s;
        is = socket.getInputStream();
        os = socket.getOutputStream();
    }


    @Override
    public void run() {

        ...
        ping();
        socket.close();
        ...
    }


    public void ping() {

        BufferedWriter writer;
        try {
            writer = new BufferedWriter(new OutputStreamWriter(os));
            writer.write("OK");
        } 
        catch (IOException e) { System.out.println("ERROR: " + e.getLocalizedMessage()); }
        finally { writer = null; }
    }

我知道我没有包含很多源代码,但这应该足以回答这个问题了。正如您所看到的,在“ping”方法中,我有一个BufferedWriter,我创建它以向远程源写入“OK”字符串。后来,我关闭了Socket。

所以我的简单问题就是这个 - 从我的理解,因为我关闭套接字,链应该是这样的:

关闭套接字---->关闭的是和os ---->关闭作家

因此,通过关闭Socket,我也在关闭并允许GC释放BufferedWriter。我是正确理解这个还是做错了什么?这对于我在其他方法(即BufferedInputStream)中初始化的所有作者和读者都是如此。通过在方法结束时将这些变量设置为null,我是否正在帮助GC区分应该释放的内容?或者我不应该这样做?

谢谢!

1 个答案:

答案 0 :(得分:3)

  

根据我的理解,因为我关闭套接字,所以链应该是这样的:

     

关闭套接字---->关闭的是和os ---->关闭作家

没有。 BufferedWriter包裹在套接字输出流中,但套接字不知道。它无法关闭它。

  

因此,通过关闭Socket,我也将关闭并允许GC释放BufferedWriter。

不,不。 BufferedWriter返回时ping()可用于GC,并且它永远不会关闭。

  

我是否正确理解

没有

  

或做错了什么?

是。您不应为每条消息创建新的BufferedWriter。您应该在套接字的生命周期中使用相同的一个,并关闭 it 而不是套接字。类似地,您应该只在套接字的生命周期中使用一个输入流或Reader。否则,您可能会丢失缓冲区中的数据。

  

对于我在其他方法(即BufferedInputStream)中初始化的所有作者和读者都是如此。

没有

  

通过在方法结束时将这些变量设置为null,我是否帮助GC区分应该释放的内容?

没有。你只是在浪费时间和空间。该方法即将退出,因此其所有局部变量都会消失。

  

或者我不应该这样做?

你不应该做任何事情。