Java关闭钩子实现

时间:2017-11-07 18:41:06

标签: java

我正在寻找如何在Java中正确实现关闭处理程序的示例。请考虑以下代码。应用程序在后台运行作为守护程序。当操作系统将SIGTERM发送到应用程序时,它必须执行清理任务。问题是如何在所有任务完成时通知App.java中的主线程。

以下代码不起作用,因为从静态方法调用component.isRunning.wait();。有人可以给我一些建议如何以一种很好的方式做到这一点吗?

App.java

package myapp;

public class App {

    final static int processorToRun=8;


    public static void main(String[] args) throws InterruptedException {

        //init component
        SoftwareComponent component=new SoftwareComponent(processorToRun);

        //start component
        component.start();

        //set shutdown hook to handle SIGTERM
        Runtime.getRuntime().addShutdownHook(getShutdownHandler(component));


        //wait until the shutdown handler stops the component
        synchronized (component.isRunning) {
            while(component.isRunning) {
                component.isRunning.wait();
            }
        }

    }

    private static Thread getShutdownHandler(SoftwareComponent component) {
        Thread handler=new Thread() {
            public void run() {
                synchronized (component.isRunning) {
                    component.stop();
                    component.isRunning.notify();
                }
            }
        };
        return handler;
    }
}

SoftwareComponent.java

package myapp;

import java.util.ArrayList;
import java.util.List;

public class SoftwareComponent {
    Boolean isRunning=true;
    private List<Processor>processors=new ArrayList<Processor>();

    public SoftwareComponent(int processorsToRun) {
        //init component

        for(int i=0;i<processorsToRun;i++) {
            processors.add(new Processor("Processor-"+i));
        }
    }

    public void start() {
        processors.forEach(processor->new Thread(processor).start());
    }

    public void stop() {
        processors.forEach(processor->processor.stop());
        isRunning=false;
    }

    public Boolean getIsRunning() {
        return isRunning;
    }
}

Processor.java

package myapp;

public class Processor implements Runnable{

    Boolean keepRunning=true;
    Boolean processingFinished;
    String  processorName;
    public Processor(String name) {
        //Init processor
        this.processorName=name;
    }

    @Override
    public void run() {
        while(keepRunning) {
            //do some cool stuff
            System.out.println(processorName+"is working.");

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void stop(){
        keepRunning=false;
        System.out.println(processorName+" stopped");
    }
}

输出:

Processor-0is working.
Processor-2is working.
Processor-4is working.
Processor-5is working.
Processor-3is working.
Processor-1is working.
Processor-7is working.
Processor-6is working.

CTRL-C pressed here

Processor-0 stopped
Processor-1 stopped
Processor-2 stopped
Processor-3 stopped
Processor-4 stopped
Processor-5 stopped
Processor-6 stopped
Processor-7 stopped
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
        at java.lang.Object.notify(Native Method)
        at myapp.App$1.run(App.java:34)

0 个答案:

没有答案