ใน Java 9 Process API รองรับวิธีง่ายๆ ในการได้ข้อมูลมากมายเกี่ยวกับ process ProcessHandle interface ระบุและให้การควบคุม native processes รวมถึงเมธอดตรวจสอบ liveness และ destroy processes ในขณะที่ ProcessHandle.Info interface ให้ snapshot ข้อมูลของ process ต้องทำลาย process ด้วยเมธอด destroy() ของ ProcessHandle interface
ตัวอย่าง: ทำลาย process
import java.io.File;
import java.io.IOException;
import java.util.Objects;
public class DestroyProcessTest {
public static void main(String[] args) throws InterruptedException {
System.out.println("---------------------------");
System.out.println("Destroy Process:");
final String javaCmd = getJavaCmdFromParent();
final String classpath = getClassPathFromParent();
try {
final Process process = new ProcessBuilder(javaCmd, "-cp", classpath, DestroyProcessTest.class.getName()).start();
ProcessHandle processHandle = process.toHandle();
printInfo(processHandle);
destroyProcess(processHandle);
Thread.sleep(1000);
System.out.println("---------------------------");
System.out.println("After destroying the process:");
printInfo(processHandle);
} catch(IOException e) {
e.printStackTrace();
}
}
private static String getClassPathFromParent() {
return System.getProperty("java.class.path", "./*");
}
private static String getJavaCmdFromParent() {
return Objects.isNull(System.getProperty("java.home")) ? "java" :
String.format("%s%sbin%sjava", System.getProperty("java.home"), File.separator, File.separator);
}
private static void destroyProcess(ProcessHandle processHandle) throws IllegalStateException {
System.out.println("Ready to destroy Process with id: " + processHandle.pid());
processHandle.destroy();
}
private static void printInfo(ProcessHandle processHandle) {
System.out.println("---------");
System.out.println("Id: " + processHandle.pid());
System.out.println("isAlive(): " + processHandle.isAlive());
System.out.println("isSupportsNormalTermination(): " + processHandle.supportsNormalTermination());
ProcessHandle.Info processInfo = processHandle.info();
System.out.println("Info: " + processInfo.toString());
System.out.println("Info arguments().isPresent(): " + processInfo.arguments().isPresent());
System.out.println("Info command().isPresent(): " + processInfo.command().isPresent());
System.out.println("Info totalCpuDuration().isPresent(): " + processInfo.totalCpuDuration().isPresent());
System.out.println("Info user().isPresent(): " + processInfo.user().isPresent());
}
}
ผลลัพธ์
---------------------------
Destroy Process:
---------
Id: 4384
isAlive(): true
isSupportsNormalTermination(): false
Info: [user: Optional[Tutorialspoint\User], cmd: C:\Program Files\Java\jdk-9.0.4\bin\java.exe, startTime: Optional[2020-03-06T10:58:53.210Z], totalTime: Optional[PT0.046875S]]
Info arguments().isPresent(): false
Info command().isPresent(): true
Info totalCpuDuration().isPresent(): true
Info user().isPresent(): true
Ready to destroy Process with id: 4384
---------------------------
After destroying the process:
---------
Id: 4384
isAlive(): false
isSupportsNormalTermination(): false
Info: [user: Optional[Tutorialspoint\User], startTime: Optional[2020-03-06T10:58:53.210Z], totalTime: Optional[PT0.109375S]]
Info arguments().isPresent(): false
Info command().isPresent(): false
Info totalCpuDuration().isPresent(): true
Info user().isPresent(): true
destroy() vs destroyForcibly()
| เมธอด | พฤติกรรม | ใช้เมื่อไหร่ |
|---|---|---|
| destroy() | Graceful termination (SIGTERM บน Unix, CTRL_BREAK บน Windows) | ปกติ ให้ process ทำ cleanup ก่อนจบ |
| destroyForcibly() | Forceful termination (SIGKILL บน Unix, TerminateProcess บน Windows) | process ค้าง ไม่ตอบสนอง destroy() |
onExit() - CompletableFuture
processHandle.onExit().thenAccept(ph -> {
System.out.println("Process " + ph.pid() + " terminated");
});
Process API ให้การจัดการ process แบบ cross-platform ไม่ต้องใช้ JNI หรือ external commands