如何在应用程序退出/类销毁时停止一个线程?

时间:2014-06-29 20:05:24

标签: java multithreading

继承人的话:

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函数,但进程保留在内存中。 (我认为垃圾收集器调用原始的finalize,而不是我的)

class A
{
    ...

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

    ...
}

如果我希望在主机类(A)死亡或应用程序完成执行时该线程结束(调用endLooping),我该怎么做?


@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();
    }

}

在A类构造函数中,我有:

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

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

当我关闭我的应用程序时,该线程仍在运行。

/ \添加meshThread.setDaemon(true);解决它

2 个答案:

答案 0 :(得分:0)

这在某种程度上取决于您的运行时。如果您有传统的jse环境,可以register a shutdown hook。 如果您在servlet容器中,则可以在context is destroyed时使用ServletContextListener。

答案 1 :(得分:0)

finalize方法:当垃圾收集确定没有对该对象的更多引用时,由对象上的垃圾回收器调用。子类重写finalize方法以处置系统资源或执行其他清理。(javadoc)。 因此,当A级结束时,并不一定意味着JVM的garabage收集器会运行。
一个不太好的方式这样做:
for(i=1;i<=2*1000;i++) { System.gc(); }
但这应该在其他一些课程中完成。方法,只有那时A的对象将由垃圾收集器收集(其中finalize将由垃圾收集器运行, IF JVM调用GC线程)。