Syncमें ह्रोनीकरण Java

एचएमबी क्या है? Syncमें ह्रोनीकरण Java?

In Javaसिंक्रोनाइजेशन का मतलब किसी भी साझा संसाधन तक कई थ्रेड्स की पहुंच को नियंत्रित करने की क्षमता से है। यह एक आदर्श विकल्प है जहां हम केवल एक थ्रेड को साझा संसाधन तक पहुंचने की अनुमति देना चाहते हैं।

निष्पादन के इस दृष्टिकोण को आम तौर पर `एसिंक्रोनस` प्रोग्रामिंग के रूप में संदर्भित किया जाता है। इन प्रोसेसर पर थ्रेड भी होते हैं, जो हल्के प्रोसेस होते हैं जो निर्देशों को एक साथ निष्पादित कर सकते हैं।

के प्रकार Syncतुल्यकालन

इसमें दो प्रकार की समन्वय विधियाँ हैं Java:

1) प्रक्रिया सिंक्रनाइज़ेशन

2) धागा तुल्यकालन.

आइये थ्रेड और प्रक्रिया सिंक्रनाइज़ेशन विस्तार से।

प्रक्रिया तुल्यकालन: यह प्रोग्रामों के बीच समन्वयन का प्रबंधन करता है। उदाहरण के लिए, `Microsoft Word` और `एक्रोबेट रीडर` अलग-अलग प्रक्रियाओं के रूप में चलते हैं।

थ्रेड सिंक्रनाइज़ेशन: दो या अधिक थ्रेड्स द्वारा महत्वपूर्ण संसाधन के समवर्ती निष्पादन को थ्रेड कहा जाता है Synchronization. आपको पारस्परिक रूप से अनन्य` और अंतर-थ्रेड संचार के लिए आगे समूहीकृत किया जा सकता है।

लॉक इन क्या है? Java?

बंद करना Java मॉनीटर या लॉक के नाम से जानी जाने वाली आंतरिक इकाई के इर्द-गिर्द निर्मित होता है। सभी ऑब्जेक्ट के साथ एक लॉक जुड़ा होता है। इसलिए, जिस थ्रेड को ऑब्जेक्ट के फ़ील्ड तक लगातार पहुँच की आवश्यकता होती है, उसे उन तक पहुँचने से पहले ऑब्जेक्ट का लॉक प्राप्त करना चाहिए, और जब काम पूरा हो जाता है तो वह लॉक रिलीज़ कर देता है। यह सुनिश्चित करता है कि एक समय में केवल एक थ्रेड ही साझा किए गए डेटा तक पहुँच सकता है।

सिंक्रोनाइजेशन के साथ मल्टीथ्रेडेड प्रोग्राम

एक बहु-थ्रेडेड प्रोग्राम एक विधि या ब्लॉक है जो समान संसाधन साझा करने वाले अन्य थ्रेड्स के हस्तक्षेप से सुरक्षित है, जिसे `synchronized` कीवर्ड का उपयोग करके इंगित किया जाता है।

समकालिक विधि का उपयोग करना

कोई भी विधि जिसे सिंक्रोनाइज़्ड के रूप में घोषित किया जाता है उसे सिंक्रोनाइज़्ड विधि के रूप में जाना जाता है। इसका उपयोग किसी भी साझा संसाधन के लिए ऑब्जेक्ट को लॉक करने के लिए भी किया जाता है। इसलिए, जब कोई थ्रेड सिंक्रोनाइज़्ड विधि को आमंत्रित करता है। यह स्वचालित रूप से उस ऑब्जेक्ट के लिए लॉक को अपने कब्जे में ले लेता है और जब वह अपना कार्य पूरा कर लेता है तो उसे रिलीज़ कर देता है।

नोट: सिंक्रोनाइज़्ड कीवर्ड क्लास और वेरिएबल के साथ काम नहीं कर सकता। कीवर्ड के साथ केवल मेथड्स और ब्लॉक का ही इस्तेमाल किया जा सकता है।

इसका उपयोग क्यों करें? Syncपवित्र विधि?

  • इसका उपयोग किसी भी साझा संसाधन के लिए ऑब्जेक्ट को लॉक करने के लिए किया जाता है।
  • जब भी सिंक्रोनाइज़्ड विधि को कॉल किया जाता है, तो ऑब्जेक्ट को लॉक मिल जाता है।
  • जब तक थ्रेड अपना कार्य पूरा नहीं कर लेता तब तक लॉक नहीं खुलता

सिंटेक्स:

Acess_modifiers synchronized return_type method_name (Method_Parameters) {
}
class MathService {
    synchronized void getSumOfArray(int[] numbers) {
     int sum = 0;

         for (int number : numbers) {
             System.out.println(Thread.currentThread()
                     .getName()
                     + " adds "
                     + sum + " to "
                     + number + " to get -> "
                     + (sum += number));

             try {
                 Thread.sleep(500);
             } catch (InterruptedException e) {
                 throw new RuntimeException(e);
             }
         }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
    }
}

कोड की व्याख्या:

इस उदाहरण को चलाएँ और देखें कि थ्रेड `0` को सबसे पहले `mathService` ऑब्जेक्ट का लॉक मिलता है और जब तक यह निष्पादित नहीं हो जाता, तब तक वह इस लॉक का विशेष रूप से उपयोग करता है। इस कोड में थ्रेड `0` और `1` आपस में जुड़े हुए नहीं हैं। आउटपुट नीचे दिखाए अनुसार है।

आउटपुट:

Thread-0 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63

सिंक्रोनाइज़्ड ब्लॉक का उपयोग करना

मान लीजिए कि आप पूरी विधि को सिंक्रोनाइज़ नहीं करना चाहते हैं। इसके बजाय, आप कोड की कुछ पंक्तियों को सिंक्रोनाइज़ करना चाहते हैं। उस समय, Synchronized ब्लॉक ने चयनित को सिंक्रनाइज़ करने में मदद की Java कोड। Syncक्रोनाइज़्ड विधि लॉक को विधि पर एक्सेस किया जाता है, जबकि सिंक्रोनाइज़्ड ब्लॉक लॉक को ऑब्जेक्ट पर एक्सेस किया जाता है।

class MathService {
    void getSumOfArray(int[] numbers) {
        synchronized (this){
            int sum = 0;

            for (int number : numbers) {
                System.out.println(Thread.currentThread()
                        .getName()
                        + " adds "
                        + sum + " to "
                        + number + " to get -> "
                        + (sum += number));

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
    }
}

कोड स्पष्टीकरण:

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

आउटपुट:

Thread-0 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63

कोड का स्पष्टीकरण:

जब आप इस कोड को चलाएँगे, तो आप देखेंगे कि यह बिना किसी व्यवधान के काम करता है, जो कि हमारी अपेक्षा थी। सिंक्रोनाइज़्ड विधि में, लॉक विधि द्वारा लागू किया जाता है, लेकिन सिंक्रोनाइज़्ड ब्लॉक विधि में, लॉक ऑब्जेक्ट द्वारा लागू किया जाता है।

स्थैतिक सिंक्रनाइज़ेशन का उपयोग करना

In Java सिंक्रोनाइज़ेशन, यदि एक से अधिक ऑब्जेक्ट हैं, तो दो थ्रेड लॉक प्राप्त कर सकते हैं और प्रत्येक ऑब्जेक्ट के लिए अलग लॉक के साथ सिंक्रोनाइज़्ड ब्लॉक या ब्लॉक में प्रवेश कर सकते हैं। इससे बचने के लिए, स्टैटिक सिंक्रोनाइज़ेशन का उपयोग किया जा सकता है। Synchronized कीवर्ड का उपयोग स्थैतिक विधियों से पहले किया जाएगा।

नोट: स्थैतिक तुल्यकालन में, लॉक एक्सेस क्लास पर होता है, ऑब्जेक्ट और विधि पर नहीं।

एकाधिक ऑब्जेक्ट लॉकिंग की समस्या को प्रदर्शित करने के लिए कोड

class MathService {
    synchronized void getSumOfArray(int[] numbers) {
            int sum = 0;

            for (int number : numbers) {
                System.out.println(Thread.currentThread()
                        .getName()
                        + " adds "
                        + sum + " to "
                        + number + " to get -> "
                        + (sum += number));

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();
        MathService mathService1 = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));
        Thread threadThree = new Thread(() ->
                mathService1.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadFour = new Thread(() ->
                mathService1.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
        threadThree.start();
        threadFour.start();
    }
}

कोड का स्पष्टीकरण:

जब हम `MathService` का दूसरा इंस्टेंस बनाते हैं, तो हम थ्रेड्स में हस्तक्षेप करते हैं क्योंकि वे दो ऑब्जेक्ट्स के साथ इंटरलीव हो जाएंगे। ध्यान दें कि थ्रेड `0` और थ्रेड `2` दो ऑब्जेक्ट्स के साथ इंटरलीव होते हैं, जबकि थ्रेड `1` और `3` दो ऑब्जेक्ट्स के साथ इंटरलीव होते हैं।

आउटपुट:

Thread-0 adds 0 to 10 to get -> 10
Thread-2 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-2 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-2 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-3 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-3 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63
Thread-3 adds 41 to 22 to get -> 63

सिंक्रोनाइज्ड स्टैटिक विधि का उपयोग करके समान कोड

class MathService {
    synchronized static void getSumOfArray(int[] numbers) {
            int sum = 0;

            for (int number : numbers) {
                System.out.println(Thread.currentThread()
                        .getName()
                        + " adds "
                        + sum + " to "
                        + number + " to get -> "
                        + (sum += number));

                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
    }
}
public class Synchronization {
    public static void main(String[] args) {
        MathService mathService = new MathService();
        MathService mathService1 = new MathService();

        Thread threadOne = new Thread(() ->
                mathService.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadTwo = new Thread(() ->
                mathService.getSumOfArray(new int[]{20, 21, 22}));
        Thread threadThree = new Thread(() ->
                mathService1.getSumOfArray(new int[]{10, 11, 12}));
        Thread threadFour = new Thread(() ->
                mathService1.getSumOfArray(new int[]{20, 21, 22}));

        threadOne.start();
        threadTwo.start();
        threadThree.start();
        threadFour.start();
    }
}

ऊपर दिए गए कोड को चलाएँ और ध्यान दें कि हमने अब थ्रेड इंटरफेरेंस को समाप्त कर दिया है। कोड का आउटपुट नीचे दिखाया गया है।

आउटपुट:

Thread-0 adds 0 to 10 to get -> 10
Thread-0 adds 10 to 11 to get -> 21
Thread-0 adds 21 to 12 to get -> 33
Thread-3 adds 0 to 20 to get -> 20
Thread-3 adds 20 to 21 to get -> 41
Thread-3 adds 41 to 22 to get -> 63
Thread-2 adds 0 to 10 to get -> 10
Thread-2 adds 10 to 11 to get -> 21
Thread-2 adds 21 to 12 to get -> 33
Thread-1 adds 0 to 20 to get -> 20
Thread-1 adds 20 to 21 to get -> 41
Thread-1 adds 41 to 22 to get -> 63

सिंक्रोनाइजेशन का उपयोग करने के लाभ

समवर्ती अनुप्रयोगों के साथ काम करने के निम्नलिखित लाभ हैं:

  • समन्वयन का मुख्य उद्देश्य Java इसका उद्देश्य थ्रेड हस्तक्षेप को रोककर असंगत डेटा को रोकना है।
  • इसमें सिंक्रोनाइज़्ड कीवर्ड है Java लॉकिंग प्रदान करता है, जो साझा संसाधन तक पारस्परिक रूप से अनन्य पहुंच सुनिश्चित करता है और डेटा रेस को रोकता है।
  • यह कोड कथनों को पुनः क्रमित करने से भी रोकता है संकलक, जो एक सूक्ष्म समवर्ती समस्या का कारण बन सकता है यदि हम अस्थिर या सिंक्रनाइज़ कीवर्ड का उपयोग नहीं करते हैं।
  • Synchronized कीवर्ड कैश की तुलना में मुख्य मेमोरी से डेटा पढ़ता है और जब यह लॉक जारी करता है।
  • यह मुख्य मेमोरी से लेखन कार्यों को भी हटा देता है, जिससे मेमोरी असंगतता संबंधी त्रुटियां दूर हो जाती हैं।

का नुकसान Syncह्रोनाइजेशन तंत्र

Syncह्रोनाइजेशन तंत्र का प्रदर्शन खराब है।

उदाहरण के लिये

  • मान लीजिए कि पाँच प्रक्रियाएँ हैं, A1, A2, A3, A4, और A5।
  • वे एक समय में एक थ्रेड तक पहुंचने के लिए साझा संसाधनों की प्रतीक्षा कर रहे हैं।
  • सभी प्रक्रियाएं प्रतीक्षा में रखी जाती हैं, इसलिए कतार में अंतिम प्रक्रिया को तब तक प्रतीक्षा करनी पड़ती है जब तक कि अन्य सभी प्रक्रियाएं पूरी न हो जाएं।

सारांश

  • Syncह्रोनाइजेशन से तात्पर्य किसी भी साझा संसाधन तक एकाधिक थ्रेड्स की पहुंच को नियंत्रित करने की क्षमता से है।
  • Java इसमें दो प्रकार की समन्वय विधियाँ हैं: 1) प्रक्रिया तुल्यकालन और 2) धागा तुल्यकालन.
  • बंद करना Java यह एक आंतरिक इकाई के चारों ओर निर्मित होता है जिसे मॉनिटर या लॉक के रूप में जाना जाता है।
  • मल्टीथ्रेडेड प्रोग्राम एक विधि या ब्लॉक है जो `synchronized` कीवर्ड का उपयोग करके इंगित समान संसाधन को साझा करने वाले अन्य थ्रेड्स के हस्तक्षेप से सुरक्षित है।
  • कोई भी विधि जिसे सिंक्रोनाइज़्ड के रूप में घोषित किया जाता है, सिंक्रोनाइज़्ड विधि के रूप में जानी जाती है।
  • In Java, सिंक्रोनाइज़्ड विधि लॉक को विधि पर एक्सेस किया जाता है, जबकि सिंक्रोनाइज़्ड ब्लॉक लॉक को ऑब्जेक्ट पर एक्सेस किया जाता है।
  • स्थैतिक तुल्यकालन में, लॉक एक्सेस क्लास पर होता है, ऑब्जेक्ट और विधि पर नहीं।
  • समन्वयन का मुख्य उद्देश्य Java इसका उद्देश्य थ्रेड हस्तक्षेप को रोककर असंगत डेटा को रोकना है।
  • इस पद्धति का सबसे बड़ा दोष यह है कि इसमें सभी प्रक्रियाओं को प्रतीक्षा में रखा जाता है, इसलिए कतार में अंतिम प्रक्रिया को तब तक प्रतीक्षा करनी पड़ती है जब तक कि अन्य सभी प्रक्रियाएं पूरी न हो जाएं।