2014-06-29 45 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线程)。

相关问题