निम्नलिखित जावा कोड को देखते हुए:जावा प्रतीक्षा()/शामिल हों(): यह डेडलॉक क्यों नहीं करता है?
public class Test {
static private class MyThread extends Thread {
private boolean mustShutdown = false;
@Override
public synchronized void run() {
// loop and do nothing, just wait until we must shut down
while (!mustShutdown) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Exception on wait()");
}
}
}
public synchronized void shutdown() throws InterruptedException {
// set flag for termination, notify the thread and wait for it to die
mustShutdown = true;
notify();
join(); // lock still being held here, due to 'synchronized'
}
}
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
try {
Thread.sleep(1000);
mt.shutdown();
} catch (InterruptedException e) {
System.out.println("Exception in main()");
}
}
}
इस रनिंग एक सेकंड के लिए प्रतीक्षा करें और फिर ठीक से बाहर निकल जाएगा। लेकिन यह मेरे लिए अप्रत्याशित है, मुझे उम्मीद है कि यहां एक मृत-ताला होना होगा।
मेरा तर्क इस प्रकार है: नव निर्मित MyThread रन() को निष्पादित करेगा, जिसे 'सिंक्रनाइज़' के रूप में घोषित किया जाता है, ताकि वह प्रतीक्षा() को कॉल कर सके और सुरक्षित रूप से 'mustShutdown' पढ़ सके; उस प्रतीक्षा() कॉल के दौरान, लॉक जारी किया जाता है और लौटने पर फिर से अधिग्रहण किया जाता है, जैसा कि प्रतीक्षा() के दस्तावेज़ीकरण में वर्णित है। एक सेकंड के बाद, मुख्य धागा शटडाउन() को निष्पादित करता है, जिसे फिर से सिंक्रनाइज़ किया जाता है क्योंकि उसी थ्रेडशॉटडाउन को उसी समय तक एक्सेस नहीं किया जा सकता है क्योंकि इसे अन्य थ्रेड द्वारा पढ़ा जा रहा है। इसके बाद यह अधिसूचना() के माध्यम से अन्य धागे को जगाता है और इसमें शामिल होने के माध्यम से पूरा होने की प्रतीक्षा करता है।
लेकिन मेरी राय में, कोई अन्य तरीका नहीं है कि दूसरा थ्रेड प्रतीक्षा() से वापस आ सकता है, क्योंकि इसे लौटने से पहले थ्रेड ऑब्जेक्ट पर लॉक फिर से हासिल करने की आवश्यकता है। ऐसा इसलिए नहीं हो सकता क्योंकि शट डाउन() अभी भी जुड़ने के दौरान लॉक रखता है()। यह अभी भी क्यों काम करता है और ठीक से बाहर निकलता है?
इस तरह के साइड इफेक्ट्स की वजह से थ्रेड सीधे फैला हुआ है। आपको एक रननेबल को लागू करना चाहिए जिसे आप थ्रेड के साथ लपेटते हैं। –