Java 9 ने Process क्लास में destroyForcibly() मेथड पेश किया जो प्रक्रियाओं को बलपूर्वक समाप्त करने का एक विश्वसनीय तरीका प्रदान करता है जब सामान्य destroy() (विनम्र समाप्ति) विफल हो जाता है या बहुत धीमा होता है।
destroy() बनाम destroyForcibly()
| पहलू | destroy() | destroyForcibly() |
|---|---|---|
| सिग्नल | SIGTERM (Unix) / CTRL_BREAK (Windows) | SIGKILL (Unix) / TerminateProcess (Windows) |
| व्यवहार | विनम्र समाप्ति का अनुरोध करता है; प्रक्रिया साफ़ कर सकती है | तत्काल बलपूर्वक समाप्ति; कोई सफाई नहीं |
| अनदेखा किया जा सकता है | हां (प्रक्रिया हैंडल/अनदेखा कर सकती है) | नहीं (OS द्वारा लागू) |
| वापसी मान | इस Process के लिए | समाप्ति अनुरोधित होने पर true |
| उपयोग केस | सामान्य शटडाउन | जमे हुए/अनुत्तरदायी प्रक्रियाएं |
मेथड सिग्नेचर
public boolean destroyForcibly()
- वापसी:
trueयदि समाप्ति सफलतापूर्वक अनुरोधित की गई,falseयदि प्रक्रिया पहले ही समाप्त हो चुकी है - थ्रेड-सुरक्षित: हां
पूर्ण उदाहरण: नोटपैड लॉन्च करें और बलपूर्वक मारें
import java.io.IOException;
import java.lang.ProcessBuilder;
public class DestroyForciblyDemo {
public static void main(String[] args) throws IOException, InterruptedException {
// ProcessBuilder का उपयोग करके नोटपैड लॉन्च करें
ProcessBuilder pb = new ProcessBuilder("notepad.exe");
Process process = pb.start();
System.out.println("नोटपैड शुरू किया गया, PID: " + process.pid());
System.out.println("5 सेकंड प्रतीक्षा...");
// उपयोगकर्ता को नोटपैड के साथ इंटरैक्ट करने का समय दें
Thread.sleep(5000);
// बलपूर्वक समाप्त करें
System.out.println("destroyForcibly() कॉल कर रहे हैं...");
boolean terminated = process.destroyForcibly();
System.out.println("समाप्ति अनुरोधित: " + terminated);
System.out.println("नोटपैड एप्लिकेशन समाप्त");
// सत्यापित करें कि यह चला गया है
Thread.sleep(500);
System.out.println("अभी भी जीवित? " + process.isAlive());
}
}
आउटपुट
नोटपैड शुरू किया गया, PID: 3728 5 सेकंड प्रतीक्षा... destroyForcibly() कॉल कर रहे हैं... समाप्ति अनुरोधित: true नोटपैड एप्लिकेशन समाप्त अभी भी जीवित? false
उन्नत: ग्रेसफुल फिर फोर्सफुल पैटर्न
सर्वोत्तम अभ्यास: पहले विनम्र समाप्ति का प्रयास करें, टाइमआउट के बाद बलपूर्वक।
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
public class GracefulThenForceful {
public static boolean terminateWithTimeout(Process process, Duration timeout) {
// 1. विनम्र समाप्ति का प्रयास करें
process.destroy();
// 2. टाइमआउट के लिए प्रतीक्षा करें
try {
if (process.waitFor(timeout.toMillis(), java.util.concurrent.TimeUnit.MILLISECONDS)) {
System.out.println("प्रक्रिया विनम्रता से समाप्त हुई");
return true;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// 3. बलपूर्वक समाप्त करें
System.out.println("टाइमआउट - बलपूर्वक समाप्त कर रहे हैं...");
boolean forced = process.destroyForcibly();
// 4. अंतिम प्रतीक्षा
try {
process.waitFor(1, java.util.concurrent.TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return forced && !process.isAlive();
}
// CompletableFuture संस्करण (गैर-ब्लॉकिंग)
public static CompletableFuture terminateAsync(Process process, Duration gracefulTimeout) {
return CompletableFuture.supplyAsync(() -> {
process.destroy();
try {
if (process.waitFor(gracefulTimeout.toMillis(), java.util.concurrent.TimeUnit.MILLISECONDS)) {
return true;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return process.destroyForcibly();
});
}
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("notepad.exe");
Process notepad = pb.start();
System.out.println("नोटपैड शुरू: PID " + notepad.pid());
Thread.sleep(3000);
boolean success = terminateWithTimeout(notepad, Duration.ofSeconds(2));
System.out.println("समाप्ति सफल: " + success);
}
}
ProcessHandle API के साथ (Java 9+)
ProcessHandle समान कार्यक्षमता प्रदान करता है लेकिन अधिक नियंत्रण के साथ:
import java.lang.ProcessHandle;
public class ProcessHandleDestroy {
public static void main(String[] args) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("notepad.exe");
Process process = pb.start();
ProcessHandle handle = process.toHandle();
System.out.println("प्रक्रिया: " + handle.pid());
Thread.sleep(3000);
// ProcessHandle के माध्यम से बलपूर्वक नष्ट करें
boolean destroyed = handle.destroyForcibly();
System.out.println("बलपूर्वक नष्ट: " + destroyed);
// onExit के साथ पूर्ण होने की प्रतीक्षा करें
handle.onExit().thenAccept(ph ->
System.out.println("पुष्टि की गई समाप्ति: " + ph.pid())
).join();
}
}
सामान्य परिदृश्य
- बाहरी उपकरण: कंपाइलर, लिंटर, फॉर्मेटर जो हैंग हो सकते हैं
- परीक्षण क्लीनअप: सुनिश्चित करें कि टेस्ट केस के बीच प्रक्रियाएं मर जाएं
- संसाधन प्रबंधन: फंसे हुए चाइल्ड प्रक्रियाओं को रोकें
- कंटेनर/ऑर्केस्ट्रेशन: Kubernetes pod समाप्ति, Docker स्टॉप
सावधानियां
- डेटा हानि: बलपूर्वक समाप्ति अनसेव्ड डेटा, भ्रष्ट फ़ाइलों, लीक संसाधनों का कारण बनती है
- ज़ोंबी प्रक्रियाएं: Unix पर, पैरेंट को अभी भी
wait()करना चाहिए - बच्चे प्रक्रियाएं:
destroyForcibly()आमतौर पर केवल पैरेंट को मारता है, बच्चों को नहीं (OS-निर्भर) - केवल अंतिम उपाय: हमेशा पहले
destroy()+ टाइमआउट का प्रयास करें