2016-10-08 22 views
5

तुल्यकालन इस कोड में सही ढंग से काम करता है:सिंक्रनाइज़ेशन दूसरे कोड में क्यों काम नहीं करता है?

class PrintNumbers { 
     synchronized public void display() { 
      System.out.println("in display"); 
      for (int i = 0; i < 3; i++) { 
       System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.getMessage(); 
       } 
      } 
      System.out.println("out of display"); 
     } 
    } 

    class MyThread implements Runnable { 
     Thread t; 
     PrintNumbers printNumbers; 

     MyThread(PrintNumbers printNumbers, String s) { 
      this.printNumbers = printNumbers; 
      t = new Thread(this,s); 
      t.start(); 
     } 

     public void run() { 
      printNumbers.display(); 
     } 
    } 

    class SyncExample { 
     public static void main(String[] args) { 
      PrintNumbers printNumbers = new PrintNumbers(); 

      new MyThread(printNumbers, "My Thread 1"); 
      new MyThread(printNumbers, "My Thread 2"); 
     } 
    } 

आउटपुट:

in display 
Thread name : My Thread 1 i= 0 
Thread name : My Thread 1 i= 1 
Thread name : My Thread 1 i= 2 
out of display 
in display 
Thread name : My Thread 2 i= 0 
Thread name : My Thread 2 i= 1 
Thread name : My Thread 2 i= 2 
out of display 

लेकिन इस कोड में:

class PrintNumbers { 
     synchronized public void display() { 
      System.out.println("in display"); 
      for (int i = 0; i < 3; i++) { 
       System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.getMessage(); 
       } 
      } 
      System.out.println("out of display"); 
     } 
    } 

    class MyThread implements Runnable { 
     Thread t; 
     PrintNumbers printNumbers; 

     MyThread(String s) { 
      this.printNumbers = new PrintNumbers(); 
      t = new Thread(this,s); 
      t.start(); 
     } 

     public void run() { 
      printNumbers.display(); 
     } 
    } 

    class SyncExample { 
     public static void main(String[] args) { 
      new MyThread("My Thread 1"); 
      new MyThread("My Thread 2"); 
     } 
    } 

आउटपुट:

in display 
Thread name : My Thread 1 i= 0 
in display 
Thread name : My Thread 2 i= 0 
Thread name : My Thread 1 i= 1 
Thread name : My Thread 2 i= 1 
Thread name : My Thread 2 i= 2 
Thread name : My Thread 1 i= 2 
out of display 
out of display 

मुझे समझ में नहीं आता कि क्या अंतर wrt सिंक्रनाइज़ेशन रननेबल MyThread में और SyncExample क्लास में PrintNumbers को प्रारंभ करने के लिए करता है। कृपया समझाएँ।

+0

गैर स्थैतिक सिंक्रनाइज़ विधियां 'इस' पर सिंक्रनाइज़ करें। – tkausl

+0

2 आपको 'डिस्प्ले' विधि स्थिर की आवश्यकता है, वे 2 ऑब्जेक्ट लॉक कर रहे हैं। – passion

+1

आप PrintNumbers के अंतर ऑब्जेक्ट का उपयोग कर रहे हैं और लॉक ऑब्जेक्ट स्तर पर है। यही कारण है कि आप अलग आउटपुट प्राप्त कर रहे हैं। – cody123

उत्तर

5

मुझे समझ में नहीं आता कि क्या अंतर wrt सिंक्रनाइज़ेशन रननेबल MyThread में और SyncExample क्लास में PrintNumbers को प्रारंभ करने के लिए करता है।

ऐसा नहीं है। मामला यह है कि आपके पहले उदाहरण में, आपके पास केवल एकPrintNumbers उदाहरण है जो दोनों थ्रेड साझा करते हैं। लेकिन आपके दूसरे उदाहरण में, आपके पास प्रत्येक थ्रेड के लिए दो अलग PrintNumbers उदाहरण हैं।

के बाद से PrintNumbers#display उदाहरण (synchronized उदाहरण तरीकों this पर सिंक्रनाइज़) पर सिंक्रनाइज़ करता है, यह केवल उदाहरण के भीतर, कई उदाहरण भर नहीं सिंक्रनाइज़ करता है।

जब दोनों धागे एक उदाहरण साझा करते हैं, तो display पर दो कॉल क्रमबद्ध होते हैं। लेकिन जब प्रत्येक धागे का अपना उदाहरण होता है, तो display पर दो कॉल अलग-अलग उदाहरणों पर होते हैं, और इस प्रकार कॉल का कोई क्रमिकरण नहीं होता है, वे ओवरलैप कर सकते हैं।

4

क्योंकि दूसरे कोड में प्रत्येक धागे का अपना PrintNumbers ऑब्जेक्ट होता है ताकि वे समानांतर में काम कर सकें। पहले में वे एकल PrintNumbers ऑब्जेक्ट साझा करते हैं और सिंक्रनाइज़ तरीके से इसके साथ काम करते हैं।

पीएस। याद रखें कि गैर-स्थैतिक तरीकों के लिए synchronized ऑब्जेक्ट पर सिंक्रनाइज़ेशन (क्लास पर स्थिर विधियों के लिए) बनाता है।

3

यह दोनों मामलों में काम कर रहा है जैसा कि इसे करना चाहिए। अंतर यह है कि पहले मामले में आपके पास एक ही वस्तु है जो सिंक्रनाइज़ होती है। दूसरे में आपके पास दो हैं। वे दोनों केवल एक बार बुलाए जाते हैं ताकि वे पूरी तरह सिंक्रनाइज़ हो जाएं।

synchronized वस्तुओं के बीच काम नहीं करता है, केवल एक के भीतर।

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