मैं यह पता लगाने की कोशिश कर रहा हूं कि सिंक्रनाइज़ तरीके कैसे काम करते हैं। मेरी समझ से मैंने दो धागे T1 और T2 बनाए हैं जो एक ही विधि को addNew कहेंगे, क्योंकि यह विधि सिंक्रनाइज़ है, क्या इसे सभी पुनरावृत्तियों को निष्पादित नहीं करना चाहिए एक धागे के लिए लूप के लिए और फिर दूसरा? आउटपुट बदलता रहता है, कभी-कभी यह इसे सही प्रिंट करता है, दूसरी बार यह T1 के मानों को T2 मानों के साथ मिश्रित करके प्रिंट करता है। कोड बहुत आसान है, क्या कोई बता सकता है कि मैं क्या गलत कर रहा हूं? शुक्रिया।

public class Main {
    public static void main(String[] args) {
        Thread t1 = new Thread(new A());
        Thread t2 = new Thread(new A());
        t1.setName("T1");
        t2.setName("T2");
        t1.start();
        t2.start();
    }
}

public class B {
    public synchronized void addNew(int i){
        Thread t = Thread.currentThread();
        for (int j = 0; j < 5; j++) {
            System.out.println(t.getName() +"-"+(j+i));
        }
    }
}

public class A extends Thread {
    private B b1 = new B();

    @Override
    public void run() {
        b1.addNew(100);
    }
}
3
Alexandre Krabbe 26 मई 2017, 18:56
2
आप B के विभिन्न इंस्टेंस के साथ सिंक्रोनाइज़ करते हैं
 – 
talex
26 मई 2017, 18:59
1
A दोनों Thread का विस्तार करते हैं और एक Thread कंस्ट्रक्टर को पास कर दिया जाता है। ऐसा नहीं होना चाहिए। Thread का विस्तार न करें, Runnable का विस्तार करें।
 – 
Lew Bloch
26 मई 2017, 19:11

3 जवाब

सबसे बढ़िया उत्तर

प्रत्येक A इंस्टेंस का अपना B इंस्टेंस होता है। विधि addNew B की एक आवृत्ति विधि है। इसलिए, addNew को कॉल के दौरान निहित रूप से प्राप्त किया गया लॉक रिसीवर B इंस्टेंस पर लॉक है। प्रत्येक थ्रेड addNew को अलग B पर कॉल कर रहा है, और इसलिए अलग-अलग तालों पर लॉक कर रहा है।

यदि आप चाहते हैं कि सभी B इंस्टेंस एक सामान्य लॉक का उपयोग करें, तो एकल साझा लॉक बनाएं, और इसे addNew के मुख्य भाग में प्राप्त करें।

9
Brian Goetz 26 मई 2017, 19:00
धन्यवाद, मैं एकल साझा लॉक बनाने के बारे में कैसे जाउंगा?
 – 
Alexandre Krabbe
26 मई 2017, 19:02
प्रत्येक वस्तु एक ताला के रूप में कार्य कर सकती है, इसलिए केवल एक ऐसा बनाएं जो B के सभी उदाहरणों में साझा किया गया हो। private static final Object lock = new Object().
 – 
Brian Goetz
26 मई 2017, 19:03
1
या प्रत्येक थ्रेड के लिए समान Runnable इंस्टेंस पास करें, जो अक्सर किया जाता है।
 – 
Lew Bloch
26 मई 2017, 19:12

दोनों A ऑब्जेक्ट की अपनी-अपनी B ऑब्जेक्ट हैं। आपको उन्हें B साझा करने की आवश्यकता है ताकि सिंक्रनाइज़ेशन का प्रभाव हो सके।

3
Kayaman 26 मई 2017, 19:00

ये कोशिश करें :

public class Main {
    public static void main(String[] args) {
        A a = new A();
        Thread t1 = new Thread(a);
        Thread t2 = new Thread(a);
        t1.setName("T1");
        t2.setName("T2");
        t1.start();
        t2.start();
    }
}

 class B {
    public synchronized void addNew(int i){
        Thread t = Thread.currentThread();
        for (int j = 0; j < 5; j++) {
            System.out.println(t.getName() +"-"+(j+i));
        }
    }
}

 class A extends Thread {
    private B b1 = new B();

    @Override
    public void run() {
        b1.addNew(100);
    }
}
0
Atul P. 27 जुलाई 2020, 09:17
1
स्पष्टीकरण कहां है, जिसे प्रश्न में पूछा गया था? साथ ही, यह निष्पादन को कैसे बदलता है? कृपया समझाएँ।
 – 
Scratte
27 जुलाई 2020, 09:23
सिंक्रनाइज़ेशन के लिए, थ्रेड को ऑब्जेक्ट को पूरी तरह से निष्पादित करने के लिए लॉक करने की आवश्यकता होती है। जब यह सिंक्रनाइज़ कोड के निष्पादन को पूरा करता है, तो यह ऑब्जेक्ट को छोड़ देता है और फिर उसी ऑब्जेक्ट को दूसरे थ्रेड द्वारा लॉक कर दिया जाता है और यह निष्पादित होता है, इस प्रकार सिंक प्राप्त होता है। और ऐसा होने के लिए, थ्रेड ऑब्जेक्ट बनाते समय उसी ऑब्जेक्ट को बहस के रूप में पारित करना होगा। पोस्ट लेखक "नए ए ()" का उपयोग बहसनेट के रूप में थ्रेड ऑब्जेक्ट्स बनाता है, इस तरह, दो अलग-अलग ऑब्जेक्ट्स पास कर रहा है। इसलिए सिंक्रनाइज़ेशन हासिल नहीं किया जाता है।
 – 
Atul P.
27 जुलाई 2020, 12:49
क्षमा करें, मैं स्पष्ट नहीं था। मेरा मतलब था कि आप इसे अपनी पोस्ट में जोड़ें :)
 – 
Scratte
27 जुलाई 2020, 12:50