आप java.lang.Thread
जावा में हत्या कैसे करते हैं ?
ExecutorStatus
इस सवाल के बारे में जवाब पसंद करता हूं : stackoverflow.com/questions/2275443/how-to-timeout-a-thread
आप java.lang.Thread
जावा में हत्या कैसे करते हैं ?
ExecutorStatus
इस सवाल के बारे में जवाब पसंद करता हूं : stackoverflow.com/questions/2275443/how-to-timeout-a-thread
जवाबों:
सूर्य द्वाराThread.stop()
इस सूत्र को देखें कि उन्होंने क्यों वंचित किया । यह इस बारे में विस्तार से जाता है कि यह एक बुरा तरीका क्यों था और सामान्य रूप से थ्रेड्स को सुरक्षित रूप से रोकने के लिए क्या किया जाना चाहिए।
जिस तरह से वे अनुशंसा करते हैं वह एक साझा चर का उपयोग एक ध्वज के रूप में करना है जो पृष्ठभूमि थ्रेड को रोकने के लिए कहता है। इस चर को थ्रेड समाप्त करने का अनुरोध करने वाली एक अलग वस्तु द्वारा सेट किया जा सकता है।
getConnection()
से java.sql.DriverManager
। यदि कनेक्शन अटैच करने में बहुत लंबा समय लगता है तो मैं कॉल करके संबंधित थ्रेड को मारने की कोशिश करता हूं, Thread.interrupt()
लेकिन यह थ्रेड को बिल्कुल प्रभावित नहीं करता है। Thread.stop()
लेकिन काम करता है, हालांकि ओरेकल अगर यह काम नहीं करना चाहिए कहते हैं interrupt()
नहीं करता है। मुझे आश्चर्य है कि यह कैसे काम करता है और पदावनत विधि का उपयोग करने से बचें।
आम तौर पर तुम नहीं ..
आप इसे थ्रेड करने के लिए कहें। यह थ्रेड.इन्टरप्ट () (javadoc लिंक) का उपयोग करके जो कुछ भी कर रहा है उसे बाधित करें
जावदोक यहाँ क्यों है की एक अच्छी व्याख्या (जावा तकनीकी लिंक)
interrupt()
विधि कहा जाता है तो थ्रेड्रिक संदर्भ @ क्या होता है? मुख्य प्रश्न प्रत्येक नए थ्रेड के लिए लॉग जनरेशन से संबंधित है ।
जावा में थ्रेड्स मारे नहीं जाते हैं, लेकिन एक थ्रेड को रोकना सहकारी तरीके से किया जाता है । थ्रेड को समाप्त करने के लिए कहा जाता है और थ्रेड को इनायत से बंद किया जा सकता है।
अक्सर एक volatile boolean
फ़ील्ड का उपयोग किया जाता है जो थ्रेड समय-समय पर जांचता है और तब समाप्त होता है जब इसे संबंधित मान पर सेट किया जाता है।
मैं यहboolean
जांचने के लिए उपयोग नहीं करूंगा कि धागा समाप्त होना चाहिए या नहीं । यदि आप volatile
एक फ़ील्ड संशोधक के रूप में उपयोग करते हैं , तो यह विश्वसनीय काम करेगा, लेकिन यदि आपका कोड अधिक जटिल हो जाता है, तो इसके बजाय while
लूप के अंदर अन्य अवरुद्ध तरीकों का उपयोग करता है , ऐसा हो सकता है, कि आपका कोड बिल्कुल भी समाप्त नहीं होगा या कम से कम आपको अधिक समय लगेगा। चाह सकता है।
कुछ अवरुद्ध पुस्तकालय विधियाँ रुकावट का समर्थन करती हैं।
हर धागे में पहले से ही एक बूलियन ध्वज बाधित स्थिति है और आपको इसका उपयोग करना चाहिए। इसे इस तरह लागू किया जा सकता है:
public void run() {
try {
while (!interrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
स्रोत कोड जावा कॉनएरेबिलिटी से प्रैक्टिस में अनुकूलित है । चूंकि cancel()
विधि सार्वजनिक है, इसलिए आप इस विधि को एक और धागा दे सकते हैं जैसा आप चाहते थे।
एक तरीका एक वर्ग चर सेट करके और एक प्रहरी के रूप में उपयोग करने से है।
Class Outer {
public static volatile flag = true;
Outer() {
new Test().start();
}
class Test extends Thread {
public void run() {
while (Outer.flag) {
//do stuff here
}
}
}
}
उपरोक्त उदाहरण में एक बाहरी वर्ग चर अर्थात ध्वज = सही सेट करें। धागे को 'मारने' के लिए इसे झूठ पर सेट करें।
volatile
यह सुनिश्चित करने के लिए "ध्वज" बनाएं कि यह हर जगह ठीक से काम करता है। आंतरिक वर्ग स्थिर नहीं है, इसलिए ध्वज को एक उदाहरण चर होना चाहिए। झंडे को एक अभिगम विधि में साफ किया जाना चाहिए ताकि अन्य संचालन (जैसे कि रुकावट) किया जा सके। "ध्वज" नाम वर्णनात्मक नहीं है।
एक तरीका है कि आप इसे कैसे कर सकते हैं। लेकिन अगर आपको इसका उपयोग करना था, तो या तो आप एक खराब प्रोग्रामर हैं या आप खराब प्रोग्रामर द्वारा लिखे गए कोड का उपयोग कर रहे हैं। इसलिए, आपको एक खराब प्रोग्रामर को रोकने या इस बुरे कोड का उपयोग करने से रोकने के बारे में सोचना चाहिए। यह समाधान केवल उन स्थितियों के लिए है जब कोई अन्य रास्ता नहीं है।
Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );
Thread.stop
भले ही वह पदावनत हो।
Thread.stop
ही करता है, लेकिन एक्सेस और अनुमतियां भी जांचता है। उपयोग करना Thread.stop
बल्कि स्पष्ट है, और मुझे इसका कारण याद नहीं है कि मैंने Thread.stop0
इसके बजाय इसका उपयोग क्यों किया । शायद Thread.stop
मेरे विशेष मामले (जावा 6 पर वेबलॉग) के लिए काम नहीं किया। या हो सकता है क्योंकि Thread.stop
पदावनत है और चेतावनी का कारण बनता है।
मैं कई टिप्पणियों को जोड़ना चाहता हूं, जो टिप्पणियों पर आधारित हैं।
Thread.stop()
यदि सुरक्षा प्रबंधक इसकी अनुमति देता है तो एक धागा बंद कर देगा।Thread.stop()
खतरनाक है। यह कहने के बाद कि, यदि आप जेईई वातावरण में काम कर रहे हैं और आपके पास बुलाया जा रहा कोड पर कोई नियंत्रण नहीं है, तो यह आवश्यक हो सकता है; देखें कि थ्रेड.स्टॉप क्यों निकाला गया है?stop()
कॉलिंग थ्रेड ThreadDeathError
पर एक नई त्रुटि बनाता है और फिर उस त्रुटि को लक्ष्य थ्रेड पर फेंकता है । इसलिए, स्टैक ट्रेस आमतौर पर बेकार है।stop()
सुरक्षा प्रबंधक के साथ जांच करता है और फिर stop1()
उस कॉल को कॉल करता है stop0()
। stop0()
मूल कोड है।Thread.stop()
(अभी तक) हटाया नहीं गया है, लेकिन Thread.stop(Throwable)
जावा 11 में हटा दिया गया था ( मेलिंग सूची , JDK-8204243 )मैं वोट दूंगा Thread.stop()
।
उदाहरण के लिए आपके पास एक लंबे समय तक चलने वाला ऑपरेशन है (जैसे नेटवर्क अनुरोध)। माना जाता है कि आप एक प्रतिक्रिया की प्रतीक्षा कर रहे हैं, लेकिन इसमें समय लग सकता है और उपयोगकर्ता अन्य UI पर नेविगेट कर सकता है। यह वेटिंग थ्रेड अब एक) बेकार बी) संभावित समस्या है क्योंकि जब वह परिणाम प्राप्त करेगा, तो यह पूरी तरह से बेकार है और वह कॉलबैक को ट्रिगर करेगा जिससे त्रुटियों की संख्या हो सकती है।
वह सब और वह प्रतिक्रिया प्रसंस्करण कर सकता है जो सीपीयू तीव्र हो सकता है। और आप, एक डेवलपर के रूप में, इसे रोक भी नहीं सकते, क्योंकि आप if (Thread.currentThread().isInterrupted())
सभी कोड में लाइनें नहीं फेंक सकते ।
तो एक धागा इसे अजीब रूप से रोकने में असमर्थता।
Thread.stop()
वैसे भी सुरक्षित रूप से कॉल नहीं कर सकते हैं । आप मतदान नहीं Thread.stop()
कर रहे हैं, आप हर उस व्यक्ति से पूछ रहे हैं जो हर ऑपरेशन को लागू करता है जो इसे सुरक्षित रूप से गर्भपात करने में लंबा समय ले सकता है। और यह अच्छी तरह से एक अच्छा विचार हो सकता है, लेकिन इसका Thread.stop()
सुरक्षित गर्भपात का अनुरोध करने के तरीके के रूप में लागू करने से कोई लेना-देना नहीं है। उसके interrupt
लिए हमारे पास पहले से ही है ।
stop
।
सवाल बल्कि अस्पष्ट है। यदि आपका मतलब है "मैं एक कार्यक्रम कैसे लिखूं ताकि जब मैं चाहता हूं तो एक थ्रेड चलना बंद हो जाए", तो विभिन्न अन्य प्रतिक्रियाएं सहायक होनी चाहिए। लेकिन अगर आपका मतलब है "मेरे पास एक सर्वर है जिसे मैं अभी पुनरारंभ नहीं कर सकता और मुझे मरने के लिए एक विशेष थ्रेड की आवश्यकता है, तो क्या हो सकता है", तो आपको निगरानी उपकरणों की तरह मैच करने के लिए एक हस्तक्षेप उपकरण की आवश्यकता है jstack
।
इस उद्देश्य के लिए मैंने jkillthread बनाया । उपयोग के लिए इसके निर्देश देखें।
निश्चित रूप से ऐसा मामला है जहां आप किसी प्रकार का नहीं, पूरी तरह से विश्वसनीय कोड चला रहे हैं। (मैं व्यक्तिगत रूप से अपने जावा वातावरण में अपलोड की गई स्क्रिप्ट को अनुमति देकर ऐसा करता हूं। हां, हर जगह सुरक्षा अलार्म घंटी बज रही है, लेकिन यह एप्लिकेशन का हिस्सा है।) इस दुर्भाग्यपूर्ण उदाहरण में आप सबसे पहले स्क्रिप्ट लेखकों से पूछकर केवल उम्मीद कर रहे हैं। कुछ प्रकार के बूलियन रन / न-रन सिग्नल का सम्मान करना। आपकी एकमात्र सभ्य विफल सुरक्षित थ्रेड पर स्टॉप विधि को कॉल करना है यदि, कहते हैं, यह कुछ समय से अधिक समय तक चलता है।
लेकिन, यह सिर्फ "सभ्य" है, और निरपेक्ष नहीं है, क्योंकि कोड थ्रेडडेट त्रुटि को पकड़ सकता है (या जो भी अपवाद आप स्पष्ट रूप से फेंकते हैं), और इसे पुन: न करें जैसे कि एक सज्जन धागे को करना चाहिए। तो, नीचे की रेखा AFAIA है कोई पूर्ण विफल सुरक्षित नहीं है।
एक धागे को इनायत करने का कोई तरीका नहीं है।
आप थ्रेड को बाधित करने की कोशिश कर सकते हैं, एक कॉमन रणनीति यह है कि थ्रेड को संदेश देने के लिए जहर की गोली का उपयोग करें ताकि खुद को रोक सकें
public class CancelSupport {
public static class CommandExecutor implements Runnable {
private BlockingQueue<String> queue;
public static final String POISON_PILL = “stopnow”;
public CommandExecutor(BlockingQueue<String> queue) {
this.queue=queue;
}
@Override
public void run() {
boolean stop=false;
while(!stop) {
try {
String command=queue.take();
if(POISON_PILL.equals(command)) {
stop=true;
} else {
// do command
System.out.println(command);
}
} catch (InterruptedException e) {
stop=true;
}
}
System.out.println(“Stopping execution”);
}
}
}
BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);
आम तौर पर आप किसी थ्रेड को नहीं मारते, रोकते या बाधित नहीं करते (या व्हीटर की जांच करें यह बाधित () है), लेकिन इसे स्वाभाविक रूप से समाप्त होने दें।
यह आसान है। आप थ्रेड की गतिविधि को नियंत्रित करने के लिए रन () विधि के अंदर (अस्थिर) बूलियन चर के साथ किसी भी लूप का उपयोग कर सकते हैं। आप इसे रोकने के लिए सक्रिय थ्रेड से मुख्य थ्रेड पर भी लौट सकते हैं।
इस तरह से आप एक धागे को इनायत करते हैं :)।
अचानक थ्रेड समाप्ति के प्रयास अच्छी तरह से ज्ञात खराब प्रोग्रामिंग अभ्यास और खराब एप्लिकेशन डिजाइन के साक्ष्य हैं। मल्टीथ्रेडेड एप्लिकेशन में सभी थ्रेड्स स्पष्ट रूप से और अंतर्निहित रूप से एक ही प्रक्रिया की स्थिति को साझा करते हैं और इसे बनाए रखने के लिए एक-दूसरे के साथ सहयोग करने के लिए मजबूर किया जाता है, अन्यथा आपका एप्लिकेशन बगों से ग्रस्त हो जाएगा, जो वास्तव में निदान करना कठिन होगा। तो, यह डेवलपर की जिम्मेदारी है कि वह सावधानी और स्पष्ट एप्लिकेशन डिजाइन के माध्यम से इस तरह की स्थिरता का आश्वासन प्रदान करे।
नियंत्रित थ्रेड समाप्ति के लिए दो मुख्य सही समाधान हैं:
अचानक थ्रेड्स समाप्ति के साथ-साथ नियंत्रित थ्रेड्स समाप्ति के गलत और सही समाधान के उदाहरणों की अच्छी और विस्तृत व्याख्या यहां पाई जा सकती है:
यहाँ इस विषय पर कुछ अच्छे लेख हैं:
मुझे एंड्रॉइड में काम करने के लिए रुकावट नहीं मिली, इसलिए मैंने इस पद्धति का उपयोग किया, पूरी तरह से काम करता है:
boolean shouldCheckUpdates = true;
private void startupCheckForUpdatesEveryFewSeconds() {
Thread t = new Thread(new CheckUpdates());
t.start();
}
private class CheckUpdates implements Runnable{
public void run() {
while (shouldCheckUpdates){
//Thread sleep 3 seconds
System.out.println("Do your thing here");
}
}
}
public void stop(){
shouldCheckUpdates = false;
}
'थ्रेड को मारना' सही वाक्यांश नहीं है। यहाँ एक तरीका यह है कि हम वसीयत को पूर्ण करने / उस पर निकलने वाले धागे से बाहर निकलने को लागू कर सकते हैं:
चलने योग्य जो मैंने उपयोग किया:
class TaskThread implements Runnable {
boolean shouldStop;
public TaskThread(boolean shouldStop) {
this.shouldStop = shouldStop;
}
@Override
public void run() {
System.out.println("Thread has started");
while (!shouldStop) {
// do something
}
System.out.println("Thread has ended");
}
public void stop() {
shouldStop = true;
}
}
ट्रिगरिंग क्लास:
public class ThreadStop {
public static void main(String[] args) {
System.out.println("Start");
// Start the thread
TaskThread task = new TaskThread(false);
Thread t = new Thread(task);
t.start();
// Stop the thread
task.stop();
System.out.println("End");
}
}
Thread.stop को हटा दिया गया है इसलिए हम जावा में एक धागा कैसे रोकें?
रद्द करने का अनुरोध करने के लिए हमेशा रुकावट विधि और भविष्य का उपयोग करें
Callable < String > callable = new Callable < String > () {
@Override
public String call() throws Exception {
String result = "";
try {
//assume below take method is blocked as no work is produced.
result = queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return result;
}
};
Future future = executor.submit(callable);
try {
String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
logger.error("Thread timedout!");
return "";
} finally {
//this will call interrupt on queue which will abort the operation.
//if it completes before time out, it has no side effects
future.cancel(true);
}
public interface CustomCallable < T > extends Callable < T > {
void cancel();
RunnableFuture < T > newTask();
}
public class CustomExecutorPool extends ThreadPoolExecutor {
protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
if (callable instanceof CancellableTask)
return ((CancellableTask < T > ) callable).newTask();
else
return super.newTaskFor(callable);
}
}
public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
public synchronized void cancel() {
try {
obj.close();
} catch (IOException e) {
logger.error("io exception", e);
}
}
public RunnableFuture < T > newTask() {
return new FutureTask < T > (this) {
public boolean cancel(boolean mayInterruptIfRunning) {
try {
this.cancel();
} finally {
return super.cancel(mayInterruptIfRunning);
}
}
};
}
}