5

如果在线程运行期间出现异常,

  1. 我需要清理或其他什么吗?
  2. 如果我有数百个线程在运行,我可以使用垃圾收集器来清理我的内存吗?

class MyThread extends Thread {

    public void run() {
        try {
            MyDAO dao = new MyDAO();
            List<Results> res = dao.findResults(...);
            ....
        } catch(Exception e) {
            //Do I need any clean up here
        }
    }
 }
4

3 回答 3

5

run方法完成时,无论是正常还是由于异常,它创建的所有对象都可以自由地被垃圾,不需要特定的清理。

您只需要清理需要关闭的资源(数据库连接、文件流等)。此清理通常finally在您的catch.

public void run(){
    Statement statement;
    try{
        MyDAO dao = new MyDAO(); // doesn't need closing
        List<Results> res = dao.findResults(...);
        statement = getStatement(); // must be closed
        ....
    } catch (Exception e){
        // handle the error
    } finally {
        if (statement!=null) statement.close();
    }
}
于 2013-05-03T12:19:14.997 回答
4

不需要特别清理,除非你有开放的系统资源,比如文件。一旦线程终止,无论是正常的还是异常的,它们都会被操作系统或虚拟机(线程堆栈,...)清除。

Thread对象本身由普通 Java GC 回收。通常,当您的内存不足时,GC 会执行收集。但是,它不是确定性的。

一般来说,为了提高内存效率,您可能会考虑将线程重构为任务和线程池,每个线程可以减少大约 1 兆字节(粗略的数字!):

  • ExecutorService在线程上运行任务的实现。如果您主要从事 CPU 工作而不是 I/O,那么拥有与内核一样多的线程而不是数百个线程通常是明智的。有现有的实现,但您也可以实现自己的执行器服务。
  • ACallable<T>是一个任务实现。也许与您可能对Runnable对象所做的事情非常相似。
  • AFuture<T>持有对任务结果的承诺。
于 2013-05-03T12:28:11.903 回答
2

当对象没有更多引用时,它们会自动进行合格的垃圾收集,因此只要您的线程中没有任何内容被其他对象引用,那么您应该没问题。

需要注意的是,Java 的垃圾收集(使用System.gc())并不能保证垃圾收集的发生。

于 2013-05-03T12:23:10.573 回答