2014-06-29 82 views
0

我的繼承人螺紋:如何在應用程序退出/類別銷燬時停止線程?

class A 
{ 
    private class MeshBuilder implements Runnable 
    { 
     private volatile boolean looping = true; 

     public void run() 
     { 
      Logger.getGlobal().log(Level.OFF, "starting new thread"); 
      while(looping) 
      { 
      } 
      Logger.getGlobal().log(Level.OFF, "closing thread"); 
     } 

     public void endLoop() 
     { 
      looping = false; 
     } 
    } 
} 

我曾嘗試重寫主類的finalize函數,但是過程中也保持在內存中。 (我認爲垃圾收集器調用原來敲定的,不是我)

class A 
{ 
    ... 

    @Override 
    protected void finalize() throws Throwable 
    { 
     meshBuilder.endLoop(); 
     super.finalize(); 
    } 

    ... 
} 

如果我想那個線程結束(調用endLooping)時,主機類(A)死亡或者當應用程序執行完畢後,我該怎麼辦呢?


@Brett OKKEN

我已經加入:

private class MeshBuilderShutdownHook implements Runnable 
{ 
    MeshBuilder meshBuilder; 
    public MeshBuilderShutdownHook(MeshBuilder meshBuilder) 
    { 
     this.meshBuilder = meshBuilder; 
    } 

    public void run() 
    { 
     Logger.getGlobal().log(Level.OFF, "MeshBuilderShutdownHook"); 
     meshBuilder.endLoop(); 
    } 

} 

而且在類的構造函數,我有:

meshBuilder = new MeshBuilder(); 
    meshThread = new Thread(meshBuilder); 
    meshThread.start(); 

    MeshBuilderShutdownHook shutdownHook = new MeshBuilderShutdownHook(meshBuilder); 
    Thread shutdownThread = new Thread(shutdownHook); 
    Runtime.getRuntime().addShutdownHook(shutdownThread); 

當我閉上我的應用,線程仍在運行。

/\ adding meshThread.setDaemon(true);解決它

+0

不適用'finalize'。 GC在某些時候會調用它。可能永遠不會。 –

回答

0

它有點取決於你的運行時間。如果你有一個傳統的jse環境,你可以register a shutdown hook。 如果你在一個servlet容器中,你可以使用一個ServletContextListener來告訴何時context is destroyed

+0

我有傳統的環境,但鉤子線程如何知道meshBuilder實例?我試過在構造函數中將meshBuilder傳遞給hookThread,然後在hookThreads運行方法中調用endLoop而沒有結果。 – Neomex

+0

您註冊爲關閉鉤子的'Thread'需要具有runnable的實現,它可以引用您的'meshBuilder'實例來關閉它。 –

+0

我已經更新了我的原始帖子,我如何試圖做到這一點。 – Neomex

0

確定方法:當垃圾收集確定沒有更多對該對象的引用時,由對象上的垃圾回收器調用。子類重寫finalize方法來處置系統資源或執行其他清理。(javadoc)。
所以當A類結束時,並不一定意味着JVM的garabage收集器已經運行。

一個不太好辦法做到這一點:
for(i=1;i<=2*1000;i++) { System.gc(); }
,但這應該在一些其他類的方法來完成,只有一個對象會被垃圾收集器收集(上敲定將運行通過垃圾收集器,如果 JVM調用GC線程)。

相關問題