如何正确关闭异步对象中的线程和文件句柄

时间:2014-11-25 16:21:04

标签: java multithreading sockets asynchronous

我正在编写一个套接字接口,希望它可以用来看起来像这样:

SocketServer server = SocketServer.connect("some server url");
server.on("connect", new SocketEvent() {
  @Override
  public void onEvent() {
    "Do something when socket is connected"
  }
}

现在我想要发生的是变量" server"超出范围,垃圾收集将会到来并最终清理干净。它不是非常重要的,它会立刻被释放。我试图避免像server.close();

这样的事情

我需要知道的是如何管理引擎盖下的线程和流的关闭。我已经读过,当垃圾收集器出现时,finalize会被调用但是每个人都说不要使用finalize。最终确定是我认为我应该处理这些事情但是有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

  

Finalize是我认为我应该处理这些事情的地方

终结器由垃圾收集调用,垃圾收集器在需要回收未使用的内存时运行。由于缺少文件描述符或数据库连接或任何其他资源,垃圾收集器运行。它运行,因为有一个交易被挂起......

不要使用finalize()来关闭资源。 http://www.informit.com/articles/article.aspx?p=1216151&seqNum=7

  

我试图避免像server.close();

这样的事情

你无法避免它。如果图书馆要求你关闭()连接,那么你必须关闭它。

您可以使用try ... finally ...来保证您的资源被关闭/清理/无论如何:

Server server;
try {
    server = ...;
    server.foo();
    server.bar();
    ...
} finally {
    if (server) {
        server.close();
    }
}

如果您的资源对象实现了Closeable,那么有一种更简洁的方法可以在Java7或Java8中运行:

try(Server server= ...) {
    server.foo();
    server.bar();
    ...
}

它被称为"尝试使用资源",它意味着与上面的try ... finally ...构造完全相同,但.close()调用是隐式的