2016-04-25 14 views
8

मैं बहु सूत्रण के लिए नया हूँ में होता है, और मैं इस उदाहरण में आए:कारण समझकर गतिरोध इस कार्यान्वयन

Thread 1: Holding lock 1... 
Thread 2: Holding lock 2... 
Thread 1: Waiting for lock 2... 
Thread 2: Waiting for lock 1... 

यानी, वहाँ एक गतिरोध है:

public class TestThread { 
    public static Object Lock1 = new Object(); 
    public static Object Lock2 = new Object(); 

    public static void main(String args[]) { 

     ThreadDemo1 T1 = new ThreadDemo1(); 
     ThreadDemo2 T2 = new ThreadDemo2(); 
     T1.start(); 
     T2.start(); 
    } 

    private static class ThreadDemo1 extends Thread { 
     public void run() { 
     synchronized (Lock1) { 
      System.out.println("Thread 1: Holding lock 1..."); 
      try { Thread.sleep(10); } 
      catch (InterruptedException e) {} 
      System.out.println("Thread 1: Waiting for lock 2..."); 
      synchronized (Lock2) { 
       System.out.println("Thread 1: Holding lock 1 & 2..."); 
      } 
     } 
     } 
    } 
    private static class ThreadDemo2 extends Thread { 
     public void run() { 
     synchronized (Lock2) { 
      System.out.println("Thread 2: Holding lock 2..."); 
      try { Thread.sleep(10); } 
      catch (InterruptedException e) {} 
      System.out.println("Thread 2: Waiting for lock 1..."); 
      synchronized (Lock1) { 
       System.out.println("Thread 2: Holding lock 1 & 2..."); 
      } 
     } 
     } 
    } 
} 

यह निम्न नमूना उत्पादन का कारण बनता है । कर सकते हैं

Thread 1: Holding lock 1... 
Thread 1: Waiting for lock 2... 
Thread 1: Holding lock 1 & 2... 
Thread 2: Holding lock 1... 
Thread 2: Waiting for lock 2... 
Thread 2: Holding lock 1 & 2... 

: हालांकि, अगर हम दूसरे सूत्र में प्राप्त ताले का क्रम बदल इतना है कि यह इस तरह अब लग रहा है:

public class TestThread { 
    public static Object Lock1 = new Object(); 
    public static Object Lock2 = new Object(); 

    public static void main(String args[]) { 

     ThreadDemo1 T1 = new ThreadDemo1(); 
     ThreadDemo2 T2 = new ThreadDemo2(); 
     T1.start(); 
     T2.start(); 
    } 

    private static class ThreadDemo1 extends Thread { 
     public void run() { 
     synchronized (Lock1) { 
      System.out.println("Thread 1: Holding lock 1..."); 
      try { Thread.sleep(10); } 
      catch (InterruptedException e) {} 
      System.out.println("Thread 1: Waiting for lock 2..."); 
      synchronized (Lock2) { 
       System.out.println("Thread 1: Holding lock 1 & 2..."); 
      } 
     } 
     } 
    } 
    private static class ThreadDemo2 extends Thread { 
     public void run() { 
     synchronized (Lock1) { 
      System.out.println("Thread 2: Holding lock 1..."); 
      try { Thread.sleep(10); } 
      catch (InterruptedException e) {} 
      System.out.println("Thread 2: Waiting for lock 2..."); 
      synchronized (Lock2) { 
       System.out.println("Thread 2: Holding lock 1 & 2..."); 
      } 
     } 
     } 
    } 
} 

यह उम्मीद काम करता है के रूप में, और एक नमूना उत्पादन इस तरह दिखता है कोई मुझे बताता है कि पहले व्यक्ति में क्या हो रहा है जो डेडलॉक पैदा कर रहा है, और दूसरे कोड में परिवर्तन इसे ठीक क्यों करता है?

उत्तर

5

यहाँ पहले मामले के लिए एक संभावित परिदृश्य है:

थ्रेड 1 अर्जित Lock1 और 10 मिलीसेकंड के लिए सोने के लिए चला जाता है। अब थ्रेड 2 Lock2 प्राप्त करता है और 10 मिलीसेकंड के लिए सो जाता है।

अब Lock2 प्राप्त करने के लिए 1 की कोशिश करता थ्रेड, लेकिन यह नहीं मिल सकता है, क्योंकि यह धागा 2 ने अधिग्रहण कर लिया है, थ्रेड 2 की कोशिश करता Lock1 जो थ्रेड 1.

द्वारा अवरोधित किया गया है दूसरे मामले में प्राप्त करने के लिए, जबकि, चलो मान लें पहला धागा चलाने के लिए चुना जाता है। यह Lock1 मिलता है, जबकि अन्य धागा अवरुद्ध है क्योंकि यह Lock1 भी प्राप्त करने का प्रयास कर रहा है। अब धागा 1 सो जाता है, और दूसरे (नेस्टेड) ​​सिंक्रनाइज़ ब्लॉक पर आगे बढ़ता है। यह इसे प्राप्त करने का प्रयास करता है (क्योंकि यह अभी भी मुफ़्त है) - अब उसे ताले मिल गए हैं। अन्य धागा अभी भी अवरुद्ध है। यह निष्पादन खत्म

के बाद ही, यह दोनों ताले विज्ञप्ति (क्योंकि यह सिंक्रनाइज़ ब्लॉक से बाहर निकलने के), और अब JVM तय करने के लिए जो धागा लेने के लिए स्वतंत्र है, लेकिन यह वास्तव में कोई फर्क नहीं पड़ता, एक ही तर्क होता है ।

+0

धन्यवाद। अब मैं पहले मामले को समझ सकता हूं। लेकिन दूसरा मामला अभी भी थोड़ा आलसी है। तो थ्रेड 2 पहले लॉक के लिए इंतजार कर रहा है। जैसे ही इसे थ्रेड 1 द्वारा जारी किया जाता है, तब क्या होता है? – SexyBeast

+0

@AttitudeMonger थ्रेड 2 इसे प्राप्त करता है और सिंक्रनाइज़ किए गए ब्लॉक के तहत पहले कथन का निष्पादन शुरू करता है। – Maroun

+0

जो 'System.out.println है ("थ्रेड 2: होल्डिंग लॉक 1 और 2 ..."); '? और यह लॉक 2 जारी करता है, जिसे थ्रेड 1 द्वारा अधिग्रहित किया जाता है, और यह 'System.out.println प्रिंट करता है ("थ्रेड 1: होल्डिंग लॉक 1 और 2 ..."); '? – SexyBeast

1

अच्छी तरह से कोड के पहले भाग में पहला धागा Lock1 धारण कर रहा है और दूसरा Lock2 स्पष्ट रूप से धारण कर रहा है। फिर वे एक दूसरे के ताले को पकड़ने की कोशिश करते हैं लेकिन वे असफल हो जाते हैं क्योंकि अन्य ताले पहले से ही दूसरे थ्रेड द्वारा आयोजित किए जा रहे हैं, इसलिए एक डेडलॉक बनाया गया है।

कोड के दूसरे भाग में हालांकि, दूसरा धागा Lock2 नहीं रख रहा है और पहले धागे को पहले लॉक को रिलीज़ होने तक कुछ भी अवरुद्ध कर दिया गया है। पहला धागा आपके आउटपुट द्वारा देखे जाने वाले दूसरे को पकड़ने के बाद पहला लॉक जारी करेगा।

2

जो आप यहां देखते हैं वह लॉक ऑर्डरिंग है, डेडलॉक रोकथाम के लिए एक आम विधि है।

अपने पहले मामले में, वर्तमान अनुदेश प्रत्येक थ्रेड के लिए चिह्नित स्थान पर स्थित संकेत के साथ निष्पादन की निम्न क्रम पर विचार करें:

Thread 1: 
    obtain lock 1 
===> 
    obtain lock 2 
    Thread 2: 
    obtain lock 2 
===> 
    obtain lock 1 

अब, धागा 1 की कोशिश करता अगले ताला 2 प्राप्त करने के लिए, लेकिन के रूप में नहीं कर सकते लॉक 2 थ्रेड 2 द्वारा आयोजित किया जाता है। और थ्रेड 2 अगले लॉक 1 प्राप्त करने का प्रयास करता है, लेकिन ऐसा नहीं कर सकता, क्योंकि यह थ्रेड 1 द्वारा आयोजित होता है। यह एक शास्त्रीय परिपत्र संसाधन निर्भरता है और इसलिए डेडलॉक में परिणाम होता है।

यह रोकने के लिए एक वैश्विक विधि यह सुनिश्चित करना है कि सभी ताले के पास कुल ऑर्डर और लॉक हमेशा उस क्रम में अधिग्रहित किए जाते हैं।

यह सबूत है कि यह काम छोटा है: क्योंकि सभी लॉक निर्भरता कुल क्रम में "नीचे की ओर" हैं, इसलिए आपके पास लॉक चक्र नहीं हो सकते हैं।

संबंधित मुद्दे