我正在寻找如何在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)