需求是:系统启动时,创建一个线程池去对任务的状态做一些处理。完成处理后,销毁线程池。
我最开始的做法是:
Refresher.getInstance().start();
Refresher.getInstance().destroy();
start()方法:
public void start() {
this.shutdownRequested = false;
refresher = new Refresher();
refresher.start();
}
destroy()方法:
public void destroy() {
while (!threadPool.getQueue().isEmpty()) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
log.warn(e.getMessage(), e);
}
}
threadPool.shutdown();
}
结果是,线程池中还没来得及创建线程,就已经销毁了。
当时不清楚原因,还在destroy()方法开始的地方加了个10秒的sleep()。这样起码有了足够的时间创建线程池。由此出发,想到创建线程池和销毁线程池既然是同步在工作,说明两者不在一个线程中。有什么方法能让销毁进程等待创建进程完成工作后再运行吗?
同事给出的答案是:thread.join()
原话是:join() is a blocking method which will wait for the end of thread。
解释:主线程中的子线程在调用join()后,join()之后的代码必须等到子线程运行结束才能够执行。
所以最终我把代码修改为:
EsbPublishTaskRefresher.getInstance().start();
public void start() {
this.shutdownRequested = false;
refresher = new Refresher();
refresher.start();
try {
refresher.join();
} catch (InterruptedException e) {
log.warn(e.getMessage(), e);
}
// destroy threadPool after work done
destroy();
}