जावा कंजिरेन्सी - व्यवधान नीतियाँ
मैं Java Concurrency प्रैक्टिस में पढ़ रहा हूँ । अध्याय में अनुभाग व्यवधान नीतियां
रद्दीकरण और शटडाउन
इसका उल्लेख किया है
किसी कार्य को उसके निष्पादित धागे की रुकावट नीति के बारे में कुछ भी ग्रहण नहीं करना चाहिए जब तक कि यह स्पष्ट रूप से एक सेवा के भीतर चलने के लिए डिज़ाइन नहीं किया गया है जिसमें एक विशिष्ट रुकावट नीति है। क्या कोई कार्य रुकावट को रद्द करने के रूप में व्याख्या करता है या रुकावट पर कुछ अन्य कार्रवाई करता है, इसे निष्पादित धागे की रुकावट की स्थिति को संरक्षित करने के लिए ध्यान रखना चाहिए। यदि इसकी इंटरफेरेडएक्ससेप्शन को इसके कॉलर तक प्रचारित नहीं किया जा रहा है, तो इसे इंटरप्टियन एक्ससेप्शन: थ्रेड.काउंटर ट्रेड () (इंटरप्ट) को पकड़ने के बाद रुकावट की स्थिति को पुनर्स्थापित करना चाहिए।
इसलिए मैंने समझने के लिए लिस्टिंग नमूने के साथ खेलने की कोशिश की। लेकिन मैं आउटपुट को लेकर उलझन में हूं।
प्राइमप्रोड्यूसर
public class CorrectPrimeProducer extends Thread {
private final BlockingQueue<BigInteger> queue;
public CorrectPrimeProducer(BlockingQueue<BigInteger> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+" interrupt status in producer:" + Thread.currentThread().isInterrupted());
BigInteger p = BigInteger.ONE;
while (!Thread.currentThread().isInterrupted()) {
queue.put(p = p.nextProbablePrime());
}
} catch (InterruptedException e) {
/* Allow thread to exit */
Thread.currentThread().interrupt();
System.out.println(Thread.currentThread().getName()+" interrupt status in producer catch:" + Thread.currentThread().isInterrupted());
}
}
}
मुख्य विधि ##
public static void main(String[] args) throws InterruptedException {
BlockingQueue<BigInteger> primes = new LinkedBlockingQueue<>();
CorrectPrimeProducer generator = new CorrectPrimeProducer(primes);
generator.start();
try {
while (needMorePrimes()) {
consume(primes.take());
}
} finally {
generator.interrupt();
}
TimeUnit.SECONDS.sleep(5);
System.out.println(generator.getName()+" interrupt status in main:"+generator.isInterrupted());
}
//do something
private static void consume(BigInteger take) {
System.out.println(take);
}
private static int counter = 1;
private static boolean needMorePrimes() {
counter++;
if(counter == 10){
// after counter reaches 10 return false
return false;
}
return true;
}
आउटपुट:
// when TimeUnit.SECONDS.sleep(5); in main class is not commented
Thread-0 interrupt status in producer:false
2
3
5
7
11
13
17
19
Thread-0 interrupt status in producer catch:true
Thread-0 interrupt status in main:false
//When TimeUnit.SECONDS.sleep(5); in main class is commented
Thread-0 interrupt status in producer:false
2
3
5
7
11
13
17
19
Thread-0 interrupt status in main:true
Thread-0 interrupt status in producer catch:true
सवाल
मुख्य कक्षा में मुख्य सूत्र में TimeUnit.SECONDS.sleep (5) जोड़कर। निष्पादित थ्रेड (यानी, जनरेटर) बाधा स्थिति रीसेट हो रही है। यदि मैं TimeUnit.SECONDS.sleep (5) विधि बताता हूं तो उस स्थिति में व्यवधान की स्थिति बरकरार रहती है। ऐसा क्यों और कैसे हो रहा है?
पुस्तक में यह उल्लिखित है कि एक धागा केवल उसके मालिक द्वारा बाधित होना चाहिए। यहाँ उपरोक्त उदाहरण में मालिक कौन है? मुझे लगता है कि इसका मुख्य तरीका सूत्र है।
जवाब
जोड़कर TimeUnit.SECONDS.sleep(5)आप थ्रेड को समाप्त करने के लिए पर्याप्त समय दे रहे हैं।
जब कोई थ्रेड समाप्त हो जाता है, तो उसका इंटरप्ट फ़्लैग साफ़ हो जाता है।
यह विनिर्देश में प्रलेखित नहीं है, लेकिन ऐसा होता है। उदाहरण के लिए देखें यह बग रिपोर्ट :
यहां किसी विनिर्देश का उल्लंघन नहीं किया जा रहा है इसलिए मैंने इसे बग के बजाय वृद्धि का अनुरोध किया है। तर्क के अनुसार विनिर्देश की कमी एक बग है - हमने जानबूझकर निर्दिष्ट किया कि "समाप्ति की आवश्यकता के बाद रुकावट का कोई प्रभाव नहीं है" इस तथ्य से निपटने के लिए कि बाधा स्थिति वीएम में संग्रहीत है और अब एक बार थ्रेड समाप्त होने के बाद मौजूद नहीं है। हालाँकि हमने थ्रेड.इज़इंटरप्टेड कल्पना में यह प्रतिबिंबित करने के लिए उपेक्षा की है।
अतिरिक्त के बिना sleep, मुझे संदेह है कि सिद्धांत में आप दोनों को देख सकते हैं trueऔर falseस्थिति को बाधित कर सकते हैं क्योंकि दौड़ की स्थिति है, लेकिन यह अधिक संभावना है कि आप trueथ्रेड शेड्यूलिंग के लिए धन्यवाद देखेंगे । टाइम विंडो जहां इंटरप्रिटेशन स्टेटस झूठा है, अपवाद को फेंके जाने के बीच है और कैच ब्लॉक में रीस्टोर की जा रही स्टेटस स्थिति अविश्वसनीय रूप से छोटी है।
मुख्य कक्षा में मुख्य सूत्र में TimeUnit.SECONDS.sleep (5) जोड़कर। निष्पादित थ्रेड (यानी, जनरेटर) बाधा स्थिति रीसेट हो रही है। यदि मैं TimeUnit.SECONDS.sleep (5) विधि बताता हूं तो उस स्थिति में व्यवधान की स्थिति बरकरार रहती है। ऐसा क्यों और कैसे हो रहा है?
आप मुख्य सूत्र के बीच किसी भी तुल्यकालन तंत्र (कतार को अवरुद्ध करने के अलावा) का उपयोग नहीं कर रहे हैं और CorrectPrimeProducerइसलिए जब मुख्य धागा स्थिति को प्रिंट करता है - तब CorrectPrimeProducerतक बाधित स्थिति को संरक्षित नहीं किया जा सकता है ( catchइस प्रकार ब्लॉक निर्देश देकर ) आप falseपरिणाम के रूप में प्राप्त कर सकते हैं ।
जब आप sleepमुख्य में जोड़ते हैं तो Threadआप केवल इस संभावना को बढ़ाते हैं कि CorrectPrimeProducerथ्रेड catchब्लॉक निर्देशों को लागू करने से पहले रुकावट की स्थिति को संरक्षित करता है, इससे पहले कि मुख्य सूत्र यह स्थिति मुद्रित करने का प्रयास करता है। इसलिए यह प्रिंट करता है true।
पुस्तक में यह उल्लिखित है कि एक धागा केवल उसके मालिक द्वारा बाधित होना चाहिए। यहाँ उपरोक्त उदाहरण में मालिक कौन है? मुझे लगता है कि इसका मुख्य तरीका सूत्र है।
इस स्थिति में आप स्वामी हैं (स्वामी वह कोड है जो थ्रेड का निर्माण करता है) CorrectPrimeProducerताकि आप यह तय कर सकें कि इसमें रुकावट का क्या अर्थ है। उदाहरण के लिए आप इसे फिर से बना सकते थे यदि यह बाधित था (उदाहरण के लिए Threadजावा थ्रेड पूल से डिफ़ॉल्ट रूप से ऐसा होता है )।