前言:
在使用線程池的時(shí)候,偶然看到了前人的代碼里出現(xiàn)了Runtime.getRuntime().addShutdownHook()。
作用:
jvm中增加一個(gè)關(guān)閉的鉤子,當(dāng)jvm關(guān)閉的時(shí)候,會(huì)執(zhí)行系統(tǒng)中已經(jīng)設(shè)置的所有通過(guò)方法addShutdownHook添加的鉤子,當(dāng)系統(tǒng)執(zhí)行完這些鉤子后,jvm才會(huì)關(guān)閉。所以這些鉤子可以在jvm關(guān)閉的時(shí)候進(jìn)行內(nèi)存清理、對(duì)象銷(xiāo)毀等操作。
使用場(chǎng)景:
多用于內(nèi)存清理,對(duì)象銷(xiāo)毀等等。
示例:
以線程池在進(jìn)程關(guān)閉時(shí)的處理。
上代碼:
private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
static {
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
close();
}
}));
}
private static void close() {
try {
System.out.println("clean");
executorService.shutdown();
System.out.println(executorService.awaitTermination(10000, TimeUnit.SECONDS));
System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
final int index = i;
try {
executorService.schedule(new Runnable() {
@Override
public void run() {
System.out.println("yes" + index);
}
}, 3, TimeUnit.SECONDS);
System.out.println("add thread");
} catch (Exception e) {
}
}
}
代碼的具體意思,不做展開(kāi),我們看結(jié)果(我們?cè)诘?次增加任務(wù)的時(shí)候,手動(dòng)kill掉這個(gè)進(jìn)程)
add thread
add thread
add thread
yes0
add thread
yes1
add thread
yes2
add thread
yes3
add thread
yes4
add thread
clean
yes5
yes6
yes7
true
end
我們可以看到,當(dāng)kill掉進(jìn)程之后,調(diào)用了close的方法。這個(gè)代碼的作用,是當(dāng)進(jìn)程關(guān)閉時(shí),我們將線程池中已經(jīng)添加的任務(wù)繼續(xù)執(zhí)行完畢,然后關(guān)閉線程池。他的作用是防止已添加的任務(wù)丟失。