2011-06-30 29 views
0

有没有什么办法可以从对象内部判断我是否超出范围?我能否告诉我是否超出范围?

我有一个必须关闭的对象。如果没有关闭,则泄漏得到保证。如果可能,我想尝试自动关闭。

我的一个私有实例变量是在关闭期间必须关闭的线程。我猜测线程的存在会导致未封闭的对象永远不会被gc'd。

保罗

+0

什么是“自动关闭”?真正理解你想达到的目标是很困难的。一个通用的解决方案是只需添加一个你不需要对象时调用的清理方法。这个方法将完成像结束线程,关闭连接等任何需要的操作。 –

回答

2

没有的“范围外范围”在Java中的概念,因为所有的对象都是在堆上。一旦你说'新',唯一能为你清理的东西就是gc。你可以使用try/finally,并且你可以有一个终结器等,但就是这样。

您需要阅读有关最终化方法,然后也许还需要了解幻影参考。

http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html

+0

我不想等到最后确定,我想在我超出范围之后立即关闭(或很快关闭)。另外,我认为finalize不会被称为,因为我内心的线索我不是GC的候选人。 – OldCurmudgeon

2

Java没有析构函数。

如果一个对象需要显式清除超出Java的内存自动垃圾回收,那么您可以提供一个明确的方法 - 例如close(),terminate()或dispose()。

如果您的线程通过持有引用来阻止对象的垃圾回收,它可能会持有weak reference,这不会阻止垃圾回收。

使用弱引用,可以判断引用的对象是否已被垃圾收集。但是,您无法分辨是否有合格用于垃圾收集。

+0

我不认为我在寻找一个析构函数,我正在寻找一个我不再可及的时刻,在这一刻我会打电话给自己关闭。 – OldCurmudgeon

+0

这可能会引用计数,就像在C++中使用boost :: shared_ptr一样。但是Java垃圾收集器可能会在不可预测的时间内检测到不可访问性,或者永远不会。所以你不能依赖终结器,并且你需要像java.io.InputStream.close()这样的显式方法。 –

0

如果您的意思与C++中的RAII是如何相似的,那么答案是否定的 - Java坚持告诉您何时不再需要某些东西,如果您需要做某些事情来清理它。通常的方式做到这一点是:

Something s = new Something(); 
try 
{ 
    // do things 
} 
finally 
{ 
    s.close(); 
} 

C#有一个using关键字是整容了一阵。

0

在研究这个时,我确实想出了一个近乎解决方案。从本质上讲,当你的Runnable被创建时,获取创建你的线程的副本,并偶尔检查它的堆栈跟踪。如果它变成空的,你可以放心地假定它们已经完成了......或者你能吗?

private void testThreads() throws InterruptedException { 

    class ThreadTest implements Runnable { 

    final Thread maker; 

    private ThreadTest() { 
     // Grab the maker's thread. 
     maker = Thread.currentThread(); 
    } 

    private boolean makerIsAlive() { 
     // If maker's stack trace hits empty it is fair to assume they are done. 
     return maker.getStackTrace().length != 0; 
    } 

    public void run() { 
     // Keep checking the stack using a stacktrace. 
     while (makerIsAlive()) { 
     try { 
      // Get out of here if maker has finished. 
      // Wait one second. 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
      break; 
     } 
     } 
     System.out.println("====== Maker has finished! Exiting. ======"); 
    } 
    } 

    Thread thread = new Thread(new ThreadTest()); 
    thread.start(); 
    // Wait for 10 seconds. 
    long finishTime = System.currentTimeMillis() + 10 * 1000; 
    while (System.currentTimeMillis() < finishTime) { 
    Thread.sleep(500); 
    } 
} 
相关问题