2012-10-26 40 views
2

我正在編寫一個多線程的java控制檯應用程序,我打算通過Ctrl-C殺死它。在這種情況下,如果我有一個封裝單個線程的類,那麼關閉封裝類finalize方法中的子線程是一種很好的做法嗎?Java使用finalize進行子線程關閉?

如果您按Ctrl-C原始應用程序並且所有線程都未正確關閉,是否有可能讓原始應用程序的工件仍在運行?

僞代碼:

public class ParentClass { 

Thread childThread = new Thread(new ExampleRunnable()); 

    @Override protected void finalize() throws Throwable { 
    childThread.shutdown(); 
    } 
} 

public class ExampleRunnable implements Runnable { 

private volatile boolean alive = false; 

@Override 
public void run() { 
    alive = true; 
    while(alive) { 
    //do some work 
    } 
} 

    public void shutdown() { 
    alive = false; 
    } 
} 
+1

不能保證finalize方法得到執行。另外,請注意,所有線程都由JVM控制,如果JVM關閉,所有線程也將死亡。 –

+0

當然,但是它有傷害和/或是否存在有益的情況? –

+1

在提供的示例中,就像在可能永遠不會執行的事情中添加努力一樣。 –

回答

3

實施finalize可以有一個非常不好的副作用。回到當天,Java很慢,其中一個原因是需要在創建的每個對象上運行finalize。現在,JVM足夠聰明,可以檢查是否存在非平凡的finalize實現,而不是盲目地將其稱爲每個正在收集的對象。只有一個類實現finalize可能並不壞,但不要養成它的習慣。

如果您想在JVM正常關閉期間做一些特殊的事情,請使用shutdown hook

+0

如果你沒有在特定的線程中做任何特殊的事情而沒有明確地關閉它,它是否安全?這對於簡單線程來說是非常標準的練習嗎 –

+0

如果您的應用程序中的每個線程都沒有關閉鉤子,那麼這是不是很糟糕的做法? –

+0

這取決於線程正在做什麼。大多數Java程序員我會說使用'ThreadPoolExecutor'而不是'new Thread'。老實說,我沒有遇到過很多人想到應用程序如何關閉,而不是自然終止。實際上,我曾經和沒有框架的人編寫服務,他們只是讓應用程序沒有清理就死掉了。我不會爲每個線程添加一個關閉鉤子來調用它。我認爲這個想法是使用關閉掛鉤來確保採取最終的行動,比如將數據提交到磁盤或乾淨地關閉網絡連接。 –