Call a non-static method from ShutdownHook

2019-08-14 04:55发布

问题:

I need to call the method a non static method removeLocksOnExit() from a ShutdownHook. the method is declared in te same class where the main is.

In the main i have the following code:

//final Thread mainThread = Thread.currentThread();
Runtime.getRuntime().addShutdownHook(new Thread() {
    public void run() {
        // remove lock file...
        removeLocksOnExit();
    }
});

The removeLocks() cannot be decared static and therefore i canot call it directly from the new thread.

The main class contains However an action listners over the windows closing which calls the method as well. Here is an extract of the code:

addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
        if (exit() == 0) {
            removeLocksOnExit();
            log.info("END");

            System.exit(0);
        }
    }
});

Perhaps i could then from the addShutdownHook fire the windows closing event. and this one will call the function fore me. ( Or create a special event for the purpose to be cached...

Is it feasible?? If yes how would you fire the event??

to have a better understanding here is the structure of my class:

public class MyTool extends JFrame{

removeLocksOnExit(){
....
...
}

 public static void main(String[] args) {
...............
.........
    //final Thread mainThread = Thread.currentThread();
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            // remove lock file...
            removeLocksOnExit();
        }
    });
}

final MyTool inst = new MyTool(args);

MyTool(String[] args) {
        super(CustomPathModel.MyTITLE);
        setResizable(false); // FIXME find a way to auto size inner xml-editor
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                if (exit() == 0) {
                    removeLocksOnExit();
                    log.info("END");

                    System.exit(0);
                }
            }
        });

        setLookFeel();
        initAdminStatus();
        initGUI();
        addToolActionListener(this);
    }
}

回答1:

You add your window-closing event in the constructor. Add the shutdown hook there as well.

Beware, however, that the removeLocks method might be called twice, from different threads. Take care that it cleans up after itself, and that it is threadsafe. Also make certain that the removeLocks method is ready to run (ie, all variables that it needs have been initialized) before you create either the window listener or the shutdown hook.



回答2:

When you create an instance of the main class you can use that object to call removeLocksOnExit()

    final MainClass object = new MainClass();
    Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            // remove lock file...
            object.removeLocksOnExit();
        }
    });

Or you can add the ShutdownHook in a non-static method.



回答3:

Simply use the reference to the object where you add the shutdown hook. I make an assumption there are no race conditions. If there are, then add whatever code you need to make it thread safe.

class SomeClass {
    void someMethod() {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
               // remove lock file...
               SomeClass.this.removeLocksOnExit();
            }
        });
    }
}