जावा में थ्रेड कैसे मारते हैं?


374

आप java.lang.Threadजावा में हत्या कैसे करते हैं ?


2
अब तक तुम एक धागे को नहीं मार सकते; क्योंकि डेड-लॉक प्रोन के कारण नष्ट () कभी भी लागू नहीं होता है
AZ_

1
मैं ExecutorStatusइस सवाल के बारे में जवाब पसंद करता हूं : stackoverflow.com/questions/2275443/how-to-timeout-a-thread
किर्बी

9
@loungerdork "मुझे लगता है कि जावा को भगोड़े धागों के लिए एक सुरक्षित स्टॉप / नष्ट विधि को लागू करना चाहिए जिस पर ताले खोने और अन्य नुकसान के बावजूद आप पर कोई नियंत्रण नहीं है" तो आप एक असुरक्षित थ्रेड स्टॉप चाहते हैं । मुझे लगता है कि आपके पास पहले से ही एक है।
डीजेकेवर्थ

4
यह आश्चर्यजनक है कि 2009 में किस तरह के प्रश्न 212 उठाव प्राप्त करेंगे। यह आज तुरंत नष्ट हो जाएगा।
जोनाथन रेनहार्ट

7
@JonathonReinhart: ऐसा क्यों है? यह एक कानूनी सवाल लगता है, इन दिनों भी। हो सकता है कि आपको यह पता न हो कि जब आपके पास भागते धागे होते हैं, तो यह किसी भी तरह से निपटने के लिए केवल पदावनत कार्यों का उपयोग कर सकता है?
17

जवाबों:


189

सूर्य द्वाराThread.stop() इस सूत्र को देखें कि उन्होंने क्यों वंचित किया । यह इस बारे में विस्तार से जाता है कि यह एक बुरा तरीका क्यों था और सामान्य रूप से थ्रेड्स को सुरक्षित रूप से रोकने के लिए क्या किया जाना चाहिए।

जिस तरह से वे अनुशंसा करते हैं वह एक साझा चर का उपयोग एक ध्वज के रूप में करना है जो पृष्ठभूमि थ्रेड को रोकने के लिए कहता है। इस चर को थ्रेड समाप्त करने का अनुरोध करने वाली एक अलग वस्तु द्वारा सेट किया जा सकता है।


1
यदि आप उस थ्रेड की जांच करते हैं जिसे आपने बाधित किया है। यह () यह आपको सही लौटाएगा और वे आपके वर्तमान थ्रेडग्रुप [] में जोड़ते रहेंगे, तो आप थ्रेडक्रंट ट्रेडरगेट.ट्रेडग्रुप () सूची का उपयोग करके इसे देख सकते हैं। यह आपके पास मौजूद सभी धागों को प्रिंट करेगा और यदि आप अपने प्रवाह को दोहराते हैं तो आपको अपने धागे के कई उदाहरण दिखाई देंगे।
अजू_

3
यदि आप एक पीसी पर हैं तो इसकी कोई समस्या नहीं है लेकिन अगर आप मोबाइल के लिए एक सॉफ्टवेयर विकसित कर रहे हैं (एंड्रॉइड मैंने इसका अनुभव किया है) तो आपको
आउटऑफमेमोरीइर्रर

2
यह सिफारिश की जा सकती है कि ध्वज के माध्यम से रोक-अनुरोध के त्वरित संचार को सुनिश्चित करने के लिए, चर को अस्थिर होना चाहिए (या चर तक पहुंच को सिंक्रनाइज़ किया जाना चाहिए), जैसा कि सिफारिश में कहा गया है।
mtsz

2
इस लिंक को इस बिंदु पर मार दिया गया है। मैं इसे आर्काइव.ओआरजी पर ढूंढने में सक्षम था, हालांकि: web.archive.org/web/20090202093154/http://java.sun.com/j2se/…
जे टेलर टेलर

2
मैं विधि का उपयोग getConnection()से java.sql.DriverManager। यदि कनेक्शन अटैच करने में बहुत लंबा समय लगता है तो मैं कॉल करके संबंधित थ्रेड को मारने की कोशिश करता हूं, Thread.interrupt()लेकिन यह थ्रेड को बिल्कुल प्रभावित नहीं करता है। Thread.stop()लेकिन काम करता है, हालांकि ओरेकल अगर यह काम नहीं करना चाहिए कहते हैं interrupt()नहीं करता है। मुझे आश्चर्य है कि यह कैसे काम करता है और पदावनत विधि का उपयोग करने से बचें।
डैनी लो

129

आम तौर पर तुम नहीं ..

आप इसे थ्रेड करने के लिए कहें। यह थ्रेड.इन्टरप्ट () (javadoc लिंक) का उपयोग करके जो कुछ भी कर रहा है उसे बाधित करें

जावदोक यहाँ क्यों है की एक अच्छी व्याख्या (जावा तकनीकी लिंक)


जब interrupt()विधि कहा जाता है तो थ्रेड्रिक संदर्भ @ क्या होता है? मुख्य प्रश्न प्रत्येक नए थ्रेड के लिए लॉग जनरेशन से संबंधित है
एबीसीडैक्टर

3
@ABcDexter पूरी बात यह है कि इंटरप्ट कुछ भी बाधित नहीं करता है, यह केवल थ्रेड में कोड को संकेत देता है (या कोड को थ्रेड द्वारा कॉल किया जा रहा है) कि किसी ने इसे जो भी कर रहा है उसे बाधित करने के लिए कहा है। थ्रेड को तब अच्छी तरह से प्रसंस्करण और वापसी को रोकने के लिए माना जाता है, जैसे कि अगर यह किया गया था कि यह क्या करना चाहिए (और उस बिंदु पर, थ्रेड संदर्भ शायद भी खारिज कर दिया गया है)। OTOH, क्या आपने वास्तव में थ्रेड को रोक दिया था, आपका प्रश्न वास्तव में अच्छा होगा और उत्तर अपरिभाषित होगा।
फ्रेड्रिक

64

जावा में थ्रेड्स मारे नहीं जाते हैं, लेकिन एक थ्रेड को रोकना सहकारी तरीके से किया जाता है । थ्रेड को समाप्त करने के लिए कहा जाता है और थ्रेड को इनायत से बंद किया जा सकता है।

अक्सर एक volatile booleanफ़ील्ड का उपयोग किया जाता है जो थ्रेड समय-समय पर जांचता है और तब समाप्त होता है जब इसे संबंधित मान पर सेट किया जाता है।

मैं यहboolean जांचने के लिए उपयोग नहीं करूंगा कि धागा समाप्त होना चाहिए या नहीं । यदि आप volatileएक फ़ील्ड संशोधक के रूप में उपयोग करते हैं , तो यह विश्वसनीय काम करेगा, लेकिन यदि आपका कोड अधिक जटिल हो जाता है, तो इसके बजाय whileलूप के अंदर अन्य अवरुद्ध तरीकों का उपयोग करता है , ऐसा हो सकता है, कि आपका कोड बिल्कुल भी समाप्त नहीं होगा या कम से कम आपको अधिक समय लगेगा। चाह सकता है।

कुछ अवरुद्ध पुस्तकालय विधियाँ रुकावट का समर्थन करती हैं।

हर धागे में पहले से ही एक बूलियन ध्वज बाधित स्थिति है और आपको इसका उपयोग करना चाहिए। इसे इस तरह लागू किया जा सकता है:

public void run() {
   try {
      while (!interrupted()) {
         // ...
      }
   } catch (InterruptedException consumed)
      /* Allow thread to exit */
   }
}

public void cancel() { interrupt(); }

स्रोत कोड जावा कॉनएरेबिलिटी से प्रैक्टिस में अनुकूलित है । चूंकि cancel()विधि सार्वजनिक है, इसलिए आप इस विधि को एक और धागा दे सकते हैं जैसा आप चाहते थे।


और यदि आप एक अविश्वसनीय कोड को प्लगइन या स्क्रिप्ट के रूप में चलाते हैं तो क्या करें? जावा में अविश्वसनीय कोड के लिए सैंडबॉक्स एम्बेडेड है। और यह सैंडबॉक्स बेकार है, यह बलपूर्वक बिना रुके काम करने की अनुमति देता है। कल्पना कीजिए कि आप जावा पर एक ब्राउज़र लिख रहे हैं। मनमानी पृष्ठ स्क्रिप्ट को मारने की क्षमता अमूल्य है।
ayvango

@ayvango फिर आपको उस स्क्रिप्ट को अपने सैंडबॉक्स में चलाना होगा। जावा सैंडबॉक्स मशीन को एप्लिकेशन से बचाता है, एक दूसरे से एप्लिकेशन के कुछ हिस्सों को नहीं।
डेविड श्वार्ट्ज

@DavidSchwartz का मतलब है, कि मुझे सिर्फ दूसरे प्लेटफॉर्म का इस्तेमाल करना चाहिए?
ayvango

@ayvango मशीन को अपने एप्लिकेशन से बचाने के लिए आप अभी भी जावा सैंडबॉक्स का उपयोग कर सकते हैं। लेकिन अगर आप अपने आवेदन के कुछ हिस्सों को अपने आवेदन के अन्य हिस्सों से बचाना चाहते हैं, तो आपको कुछ उपकरण चुनने होंगे, जो ऐसा कर सकते हैं।
डेविड श्वार्ट्ज

@DavidSchwartz ASFAIK ऐसे उपकरण मौजूद नहीं हो सकते यदि यह प्लेटफ़ॉर्म स्तर पर समर्थित नहीं है। लेकिन निश्चित रूप से पूरी तरह से व्याख्या किए गए स्क्रिप्ट इंजन के साथ कार्य को हल किया जा सकता है। यह erlang करता है और अन्य सामान की तरह कटौती की गणना कर सकता है।
ayvango

20

एक तरीका एक वर्ग चर सेट करके और एक प्रहरी के रूप में उपयोग करने से है।

Class Outer {
    public static volatile flag = true;

    Outer() {
        new Test().start();
    }
    class Test extends Thread {

        public void run() {
            while (Outer.flag) {
                //do stuff here
            }
        }
    }

}

उपरोक्त उदाहरण में एक बाहरी वर्ग चर अर्थात ध्वज = सही सेट करें। धागे को 'मारने' के लिए इसे झूठ पर सेट करें।


2
बस एक तरफ संकेत के रूप में: ध्वज के रूप में एक चर केवल काम करता है, जब धागा चलता है और यह अटक नहीं है। Thread.interrupt () थ्रेड को अधिकांश प्रतीक्षा स्थितियों (प्रतीक्षा, नींद, नेटवर्क रीड, और इसी तरह) से मुक्त करना चाहिए। इसलिए आपको इस काम को करने के लिए कभी भी InterruptedException को नहीं पकड़ना चाहिए।
रेनेस

12
यह विश्वसनीय नहीं है; volatileयह सुनिश्चित करने के लिए "ध्वज" बनाएं कि यह हर जगह ठीक से काम करता है। आंतरिक वर्ग स्थिर नहीं है, इसलिए ध्वज को एक उदाहरण चर होना चाहिए। झंडे को एक अभिगम विधि में साफ किया जाना चाहिए ताकि अन्य संचालन (जैसे कि रुकावट) किया जा सके। "ध्वज" नाम वर्णनात्मक नहीं है।
एरिकनसन

2
मुझे रन विधि में "जबकि" बात नहीं मिलती है। क्या इसका मतलब यह नहीं है कि रन पद्धति में जो कुछ भी लिखा गया है उसे दोहराया जाएगा? यह कुछ ऐसा नहीं है जिसे हम पहले स्थान पर करना चाहते थे :(

2
+1 करते समय ((Thread.currentThread) (। IsInteruppted ()) को प्राथमिकता दी जाती है
Toby

2
दोनों मामले विफल हो जाते हैं, उदाहरण के लिए जब आप बाहरी प्रक्रिया को खोलते हैं, जबकि {// ओपन एक्सट्रीम प्रोसेस} और उस प्रक्रिया को लटका दिया जाता है, तो अब न तो धागा बाधित होगा और न ही यह आपकी बूलियन स्थिति की जांच करने के लिए अंत तक पहुंचेगा, और आप हैं छोड़ दिया लटक रहा है ... उदाहरण के लिए java.exec का उपयोग करके एक अजगर कंसोल लॉन्च करें और इसे बाहर निकलने के बिना नियंत्रण वापस पाने का प्रयास करें, और देखें कि क्या उस प्रक्रिया को मारने और बाहर निकलने का कोई तरीका है .... इसे देखने का कोई तरीका नहीं है। ऐसी स्थिति से बाहर निकलें ...
स्पेस रॉकर

11

एक तरीका है कि आप इसे कैसे कर सकते हैं। लेकिन अगर आपको इसका उपयोग करना था, तो या तो आप एक खराब प्रोग्रामर हैं या आप खराब प्रोग्रामर द्वारा लिखे गए कोड का उपयोग कर रहे हैं। इसलिए, आपको एक खराब प्रोग्रामर को रोकने या इस बुरे कोड का उपयोग करने से रोकने के बारे में सोचना चाहिए। यह समाधान केवल उन स्थितियों के लिए है जब कोई अन्य रास्ता नहीं है।

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() );

2
ऐसा करने के लिए कोई कारण नहीं हैं, क्योंकि यह अभी भी जनता को कॉल करना संभव है, Thread.stopभले ही वह पदावनत हो।
Lii

1
@ एलआईआई Thread.stopही करता है, लेकिन एक्सेस और अनुमतियां भी जांचता है। उपयोग करना Thread.stopबल्कि स्पष्ट है, और मुझे इसका कारण याद नहीं है कि मैंने Thread.stop0इसके बजाय इसका उपयोग क्यों किया । शायद Thread.stopमेरे विशेष मामले (जावा 6 पर वेबलॉग) के लिए काम नहीं किया। या हो सकता है क्योंकि Thread.stopपदावनत है और चेतावनी का कारण बनता है।
वादिमपलाटनोव

1
मेरे परिदृश्य में यह अंतहीन चलने वाले धागे को रोकने का एकमात्र तरीका था। कुछ कारण के लिए .stop () ने धागा बंद नहीं किया, लेकिन stop0 () ने किया
फिफ्फी

10

मैं कई टिप्पणियों को जोड़ना चाहता हूं, जो टिप्पणियों पर आधारित हैं।

  1. Thread.stop() यदि सुरक्षा प्रबंधक इसकी अनुमति देता है तो एक धागा बंद कर देगा।
  2. Thread.stop()खतरनाक है। यह कहने के बाद कि, यदि आप जेईई वातावरण में काम कर रहे हैं और आपके पास बुलाया जा रहा कोड पर कोई नियंत्रण नहीं है, तो यह आवश्यक हो सकता है; देखें कि थ्रेड.स्टॉप क्यों निकाला गया है?
  3. आपको कंटेनर कर्मचारी थ्रेड को कभी भी बंद नहीं करना चाहिए। यदि आप उस कोड को चलाना चाहते हैं, जो लटका हुआ है, (सावधानी से) एक नया डेमॉन थ्रेड शुरू करें और इसकी निगरानी करें, यदि आवश्यक हो तो हत्या।
  4. stop()कॉलिंग थ्रेड ThreadDeathErrorपर एक नई त्रुटि बनाता है और फिर उस त्रुटि को लक्ष्य थ्रेड पर फेंकता है । इसलिए, स्टैक ट्रेस आमतौर पर बेकार है।
  5. JRE 6 में, stop()सुरक्षा प्रबंधक के साथ जांच करता है और फिर stop1()उस कॉल को कॉल करता है stop0()stop0()मूल कोड है।
  6. जावा 13 के रूप में Thread.stop()(अभी तक) हटाया नहीं गया है, लेकिन Thread.stop(Throwable)जावा 11 में हटा दिया गया था ( मेलिंग सूची , JDK-8204243 )

8

मैं वोट दूंगा Thread.stop()

उदाहरण के लिए आपके पास एक लंबे समय तक चलने वाला ऑपरेशन है (जैसे नेटवर्क अनुरोध)। माना जाता है कि आप एक प्रतिक्रिया की प्रतीक्षा कर रहे हैं, लेकिन इसमें समय लग सकता है और उपयोगकर्ता अन्य UI पर नेविगेट कर सकता है। यह वेटिंग थ्रेड अब एक) बेकार बी) संभावित समस्या है क्योंकि जब वह परिणाम प्राप्त करेगा, तो यह पूरी तरह से बेकार है और वह कॉलबैक को ट्रिगर करेगा जिससे त्रुटियों की संख्या हो सकती है।

वह सब और वह प्रतिक्रिया प्रसंस्करण कर सकता है जो सीपीयू तीव्र हो सकता है। और आप, एक डेवलपर के रूप में, इसे रोक भी नहीं सकते, क्योंकि आप if (Thread.currentThread().isInterrupted())सभी कोड में लाइनें नहीं फेंक सकते ।

तो एक धागा इसे अजीब रूप से रोकने में असमर्थता।


यदि नेटवर्क ऑपरेशन पहले से ही सुरक्षित रूप से गर्भपात योग्य है, तो बस थ्रेड को बाधित करें। यदि नेटवर्क ऑपरेशन सुरक्षित रूप से गर्भपात योग्य नहीं है, तो आप Thread.stop()वैसे भी सुरक्षित रूप से कॉल नहीं कर सकते हैं । आप मतदान नहीं Thread.stop()कर रहे हैं, आप हर उस व्यक्ति से पूछ रहे हैं जो हर ऑपरेशन को लागू करता है जो इसे सुरक्षित रूप से गर्भपात करने में लंबा समय ले सकता है। और यह अच्छी तरह से एक अच्छा विचार हो सकता है, लेकिन इसका Thread.stop()सुरक्षित गर्भपात का अनुरोध करने के तरीके के रूप में लागू करने से कोई लेना-देना नहीं है। उसके interruptलिए हमारे पास पहले से ही है ।
डेविड श्वार्ट्ज

"तो एक धागा इसे अजीब रूप से रोकने में असमर्थता।" - ... जब तक आप गहराई से नहीं दिखते (जैसा कि जावा डिजाइनरों ने किया है) और निष्कर्ष निकालते हैं कि कोई भी तकनीकी रूप से व्यवहार्य समाधान नहीं हैं जो अपवित्र करने से बदतर नहीं हैं stop
स्टीफन सी

5

सवाल बल्कि अस्पष्ट है। यदि आपका मतलब है "मैं एक कार्यक्रम कैसे लिखूं ताकि जब मैं चाहता हूं तो एक थ्रेड चलना बंद हो जाए", तो विभिन्न अन्य प्रतिक्रियाएं सहायक होनी चाहिए। लेकिन अगर आपका मतलब है "मेरे पास एक सर्वर है जिसे मैं अभी पुनरारंभ नहीं कर सकता और मुझे मरने के लिए एक विशेष थ्रेड की आवश्यकता है, तो क्या हो सकता है", तो आपको निगरानी उपकरणों की तरह मैच करने के लिए एक हस्तक्षेप उपकरण की आवश्यकता है jstack

इस उद्देश्य के लिए मैंने jkillthread बनाया । उपयोग के लिए इसके निर्देश देखें।


धन्यवाद! ठीक वही जो मेरे द्वारा खोजा जा रहा था!
डेनिस कोकोरिन

4

निश्चित रूप से ऐसा मामला है जहां आप किसी प्रकार का नहीं, पूरी तरह से विश्वसनीय कोड चला रहे हैं। (मैं व्यक्तिगत रूप से अपने जावा वातावरण में अपलोड की गई स्क्रिप्ट को अनुमति देकर ऐसा करता हूं। हां, हर जगह सुरक्षा अलार्म घंटी बज रही है, लेकिन यह एप्लिकेशन का हिस्सा है।) इस दुर्भाग्यपूर्ण उदाहरण में आप सबसे पहले स्क्रिप्ट लेखकों से पूछकर केवल उम्मीद कर रहे हैं। कुछ प्रकार के बूलियन रन / न-रन सिग्नल का सम्मान करना। आपकी एकमात्र सभ्य विफल सुरक्षित थ्रेड पर स्टॉप विधि को कॉल करना है यदि, कहते हैं, यह कुछ समय से अधिक समय तक चलता है।

लेकिन, यह सिर्फ "सभ्य" है, और निरपेक्ष नहीं है, क्योंकि कोड थ्रेडडेट त्रुटि को पकड़ सकता है (या जो भी अपवाद आप स्पष्ट रूप से फेंकते हैं), और इसे पुन: न करें जैसे कि एक सज्जन धागे को करना चाहिए। तो, नीचे की रेखा AFAIA है कोई पूर्ण विफल सुरक्षित नहीं है।


AFAIK अधिक से अधिक सेवाएं हाइब्रिड होती जा रही हैं और 3rd पार्टी कोड (प्लगइन, स्क्रिप्ट आदि) को निष्पादित करने के लिए प्रबंधित वातावरण का उपयोग करते हैं, जो कोड पर पूरी तरह से नियंत्रण नहीं रखते हैं, यह पूरी तरह से थ्रेड को बंद करने के लिए अनुचित लगता है। चूंकि सेवा इंजीनियरों के लिए, एक जीवित और सेवारत राज्य एक गैर सेवारत राज्य की तुलना में असीम रूप से बेहतर हो सकता है (या तो फांसी के कारण (जो थ्रेड्स ले जाता है), या व्यस्त अनंत लूपिंग (जो कोर ले जाता है))
वेइपेंग एल

3

एक धागे को इनायत करने का कोई तरीका नहीं है।

आप थ्रेड को बाधित करने की कोशिश कर सकते हैं, एक कॉमन रणनीति यह है कि थ्रेड को संदेश देने के लिए जहर की गोली का उपयोग करें ताकि खुद को रोक सकें

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”);

http://anandsekar.github.io/cancel-support-for-threads/


2

आम तौर पर आप किसी थ्रेड को नहीं मारते, रोकते या बाधित नहीं करते (या व्हीटर की जांच करें यह बाधित () है), लेकिन इसे स्वाभाविक रूप से समाप्त होने दें।

यह आसान है। आप थ्रेड की गतिविधि को नियंत्रित करने के लिए रन () विधि के अंदर (अस्थिर) बूलियन चर के साथ किसी भी लूप का उपयोग कर सकते हैं। आप इसे रोकने के लिए सक्रिय थ्रेड से मुख्य थ्रेड पर भी लौट सकते हैं।

इस तरह से आप एक धागे को इनायत करते हैं :)।


1

अचानक थ्रेड समाप्ति के प्रयास अच्छी तरह से ज्ञात खराब प्रोग्रामिंग अभ्यास और खराब एप्लिकेशन डिजाइन के साक्ष्य हैं। मल्टीथ्रेडेड एप्लिकेशन में सभी थ्रेड्स स्पष्ट रूप से और अंतर्निहित रूप से एक ही प्रक्रिया की स्थिति को साझा करते हैं और इसे बनाए रखने के लिए एक-दूसरे के साथ सहयोग करने के लिए मजबूर किया जाता है, अन्यथा आपका एप्लिकेशन बगों से ग्रस्त हो जाएगा, जो वास्तव में निदान करना कठिन होगा। तो, यह डेवलपर की जिम्मेदारी है कि वह सावधानी और स्पष्ट एप्लिकेशन डिजाइन के माध्यम से इस तरह की स्थिरता का आश्वासन प्रदान करे।

नियंत्रित थ्रेड समाप्ति के लिए दो मुख्य सही समाधान हैं:

  • साझा वाष्पशील ध्वज का उपयोग
  • Thread.interrupt () और Thread.interrupted () विधियों की जोड़ी का उपयोग।

अचानक थ्रेड्स समाप्ति के साथ-साथ नियंत्रित थ्रेड्स समाप्ति के गलत और सही समाधान के उदाहरणों की अच्छी और विस्तृत व्याख्या यहां पाई जा सकती है:

https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads


चूंकि प्रोग्राम अब एकल डेवलपर द्वारा नहीं लिखे जाते हैं, इसलिए थ्रेड्स को मारना अक्सर आवश्यक होता है। इसलिए खराब प्रोग्रामिंग नहीं मानी जा सकती। मैं मारने के बिना लिनक्स की कल्पना नहीं कर सकता। धागे को मारने में असमर्थता जावा दोष है।
पावेल निदोबा

1
बहुत बढ़िया, मिस्टर राइट ... क्या होगा अगर आपको कुछ 3 पार्टी लाइब्रेरी को कॉल करना है, जिस पर आपका कोई नियंत्रण नहीं है और जिसमें एक छोटी गाड़ी है और निष्पादित होने पर हर 1000-2000 बार एक बार लटक सकती है? बुरा प्रोग्रामिंग अभ्यास हुह? वैसे आपके पास हमेशा उस कोड तक पहुंच नहीं हो सकती है जिसका आप उपयोग कर रहे हैं। वैसे भी, ओप पूछ रहा है कि एक धागे को कैसे मारना है न कि अपने कोड को डिज़ाइन करते समय इसके प्रवाह को कैसे नियंत्रित किया जाए ...
आर्टुरस एम

सवाल यह है कि क्या होगा जब आप एक थ्रेड को मारते हैं, जिसके पास म्यूटेक्स है या कुछ मेमोरी ब्लॉक आवंटित किया गया है, या जिसे कुछ घटना या डेटा उत्पन्न करना चाहिए जो दूसरे थ्रेड का इंतजार कर रहा है? आपके आवेदन के बाकी तर्क के साथ क्या होगा? आपको हमेशा यह जोखिम रहेगा कि छोटी और स्पष्ट समस्या को जटिल समस्या में बदल दिया जाएगा, जिसे पुन: पेश करना और जांच करना कठिन होगा। धागे को मारना असुरक्षित है क्योंकि यह आपके आवेदन को विभिन्न असंगत अवस्थाओं में छोड़ सकता है। Cert.org पर लिंक से जानकारी पर एक नज़र डालें।
जरथुस्से

हमारे पास एक नियंत्रित धागा है जो कुछ शर्तों पर यह तय कर सकता है कि पूरी गणना बस व्यर्थ हो गई। वास्तविक काम करने वाले कई अलग-अलग रनवे को किसी भी सुविधाजनक स्थान पर isInterrupted () के कुछ प्रकार के साथ छींटे की जरूरत है - कितना भयानक! यह बहुत अच्छा है अगर कंट्रोलर थ्रेड डाउन का कारण बनता है, जो कहीं से भी बाहर नहीं निकलता है, सफाई से सभी सिंक्रनाइज़ और अंत में ब्लॉक को खोल देता है। हर कोई कहता है कि यह बहुत त्रुटि वाला है, लेकिन काफी असंबंधित थ्रेड्स के लिए, मुझे ऐसा क्यों नहीं दिखता।
डेनियल


1

मुझे एंड्रॉइड में काम करने के लिए रुकावट नहीं मिली, इसलिए मैंने इस पद्धति का उपयोग किया, पूरी तरह से काम करता है:

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;
 }

2
वाष्पशील कीवर्ड को shouldCheckUpdates में जोड़ा जाना चाहिए, संकलक को थ्रेड स्थानीय भंडारण के साथ अनुकूलित करता है।
क्लिनक्स

1

'थ्रेड को मारना' सही वाक्यांश नहीं है। यहाँ एक तरीका यह है कि हम वसीयत को पूर्ण करने / उस पर निकलने वाले धागे से बाहर निकलने को लागू कर सकते हैं:

चलने योग्य जो मैंने उपयोग किया:

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");

    }

}

यदि कंपाइलर थ्रेड लोकल स्टोरेज के साथ अनुकूलन करता है, तो वाष्पशील कीवर्ड को कंधों के वेरिएबल में जोड़ा जाना चाहिए।
ओलेक्सीii किस्लीत्सिन

0

Thread.stop को हटा दिया गया है इसलिए हम जावा में एक धागा कैसे रोकें?

रद्द करने का अनुरोध करने के लिए हमेशा रुकावट विधि और भविष्य का उपयोग करें

  1. जब कार्य सिग्नल को बाधित करने के लिए प्रतिक्रिया करता है, उदाहरण के लिए, कतार लेने की विधि को अवरुद्ध करना।
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);
}
  1. जब कार्य सिग्नल को बाधित करने के लिए प्रतिक्रिया नहीं देता है। कार्य को सॉकेट I / O करता है जो सिग्नल को बाधित करने पर प्रतिक्रिया नहीं देता है और इस प्रकार उपरोक्त दृष्टिकोण का उपयोग करने से कार्य समाप्त नहीं होगा, भविष्य में समय समाप्त हो जाएगा लेकिन अंत में ब्लॉक का कोई प्रभाव नहीं पड़ेगा। , धागा सॉकेट को सुनता रहेगा। हम सॉकेट बंद कर सकते हैं या यदि पूल द्वारा कार्यान्वित किया जाता है तो कनेक्शन बंद कर सकते हैं।
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);
                }
            }

        };
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.