简体   繁体   中英

How to stop a thread on application exit / class destruction?

Heres my thread:

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;
        }
    }
}

I have tried overriding host class finalize function, but process stays in memory. ( I think garbage collector calls original finalize, not mine )

class A
{
    ...

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

    ...
}

If I want that thread to end (call endLooping) when host class (A) dies or when application finishes executing, how do I do that?


@Brett Okken

I have added:

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

}

And in class A constructor I have:

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

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

And when I close my application, the thread is still running.

/\\ adding meshThread.setDaemon(true); solves it

It somewhat depends on what your runtime is. If you have a traditional jse environment, you can register a shutdown hook . If you are in a servlet container, you can use a ServletContextListener to be told when the context is destroyed .

finalize method : Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. A subclass overrides the finalize method to dispose of system resources or to perform other cleanup. (javadoc).
so when class A ends, it doesn't necessarily mean that JVM's garabage collector would have run.

a not so good way to do it:
for(i=1;i<=2*1000;i++) { System.gc(); }
but this should be done in some other class' method, only then object of A will be collected by garbage collector(on which finalize will be run by garbage collector, IF JVM invokes GC thread).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM