java - 'सिंक्रनाइज़' का अर्थ क्या है?




multithreading keyword (10)

सिंक्रनाइज़ किए गए कीवर्ड क्या है?

थ्रेड मुख्य रूप से फ़ील्ड तक पहुंच साझा करके संवाद करते हैं और ऑब्जेक्ट संदर्भ फ़ील्ड संदर्भित करते हैं। संचार का यह रूप बेहद कुशल है, लेकिन दो प्रकार की त्रुटियों को संभव बनाता है: थ्रेड हस्तक्षेप और स्मृति स्थिरता त्रुटियां । इन त्रुटियों को रोकने के लिए आवश्यक उपकरण सिंक्रनाइज़ेशन है।

सिंक्रनाइज़ किए गए ब्लॉक या विधियां थ्रेड हस्तक्षेप को रोकती हैं और सुनिश्चित करती हैं कि डेटा सुसंगत है। किसी भी समय, केवल एक थ्रेड लॉक प्राप्त करके सिंक्रनाइज़ ब्लॉक या विधि ( महत्वपूर्ण अनुभाग ) तक पहुंच सकता है। अन्य धागे महत्वपूर्ण खंड तक पहुंचने के लिए ताला की रिहाई के लिए इंतजार करेंगे।

विधियों को सिंक्रनाइज़ करते समय कब होते हैं?

जब आप विधि परिभाषा या घोषणा में सिंक्रनाइज़ करते हैं तो तरीके सिंक्रनाइज़ होते हैं। आप एक विधि में कोड के एक विशेष ब्लॉक को सिंक्रनाइज़ भी कर सकते हैं।

व्याकरणिक रूप से और तार्किक रूप से इसका क्या अर्थ है?

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

यह एक जादू के साथ नहीं किया जा सकता है। आवेदन में महत्वपूर्ण अनुभाग (ओं) की पहचान करने और तदनुसार इसकी रक्षा करने के लिए प्रोग्रामर जिम्मेदारी है। जावा आपके आवेदन की रक्षा के लिए एक ढांचा प्रदान करता है, लेकिन जहां और किस वर्ग की रक्षा की जानी चाहिए वह प्रोग्रामर की ज़िम्मेदारी है।

जावा दस्तावेज page से अधिक जानकारी

आंतरिक ताले और सिंक्रनाइज़ेशन:

सिंक्रनाइज़ेशन एक आंतरिक इकाई के आसपास बनाया गया है जिसे आंतरिक लॉक या मॉनिटर लॉक के नाम से जाना जाता है। आंतरिक ताले सिंक्रनाइज़ेशन के दोनों पहलुओं में एक भूमिका निभाते हैं: किसी ऑब्जेक्ट के राज्य में विशेष पहुंच लागू करना और दृश्यता से पहले संबंधों से पहले होता है।

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

एक धागा को लॉक हासिल करने के दौरान आंतरिक लॉक के मालिक होने के लिए कहा जाता है और लॉक जारी किया जाता है। जब तक एक थ्रेड एक आंतरिक लॉक का मालिक होता है, तब तक कोई अन्य धागा एक ही लॉक प्राप्त नहीं कर सकता है। जब यह ताला हासिल करने का प्रयास करता है तो दूसरा धागा अवरुद्ध होगा।

जब एक थ्रेड एक आंतरिक लॉक जारी करता है, तो उस क्रिया के बीच एक पूर्व-संबंध संबंध स्थापित होता है और उसी लॉक के बाद के अधिग्रहण के बाद होता है।

सिंक्रनाइज़ किए गए तरीकों को बनाने के दो effects :

सबसे पहले, एक ही ऑब्जेक्ट पर इंटरलिव पर सिंक्रनाइज़ किए गए तरीकों के दो आमंत्रणों के लिए यह संभव नहीं है।

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

दूसरा, जब एक सिंक्रनाइज़ विधि बाहर निकलती है, तो यह स्वचालित रूप से एक ही ऑब्जेक्ट के लिए एक सिंक्रनाइज़ विधि के बाद के किसी भी आमंत्रण के साथ होता है।

यह गारंटी देता है कि वस्तु की स्थिति में परिवर्तन सभी धागे के लिए दृश्यमान हैं।

सिंक्रनाइज़ेशन के अन्य विकल्पों की तलाश करें:

जावा में सिंक्रनाइज़ (यह) से बचें?

मेरे पास synchronized कीवर्ड के उपयोग और महत्व के संबंध में कुछ प्रश्न हैं।

  • synchronized कीवर्ड का महत्व क्या है?
  • तरीकों को synchronized किया जाना चाहिए?
  • प्रोग्रामेटिक और तार्किक रूप से इसका क्या अर्थ है?

अवलोकन

जावा में सिंक्रनाइज़ किए गए कीवर्ड को थ्रेड-सुरक्षा के साथ करना होता है, यानी, जब एकाधिक थ्रेड एक ही चर को पढ़ते या लिखते हैं।
यह सीधे हो सकता है (एक ही चर का उपयोग करके) या परोक्ष रूप से (एक वर्ग का उपयोग करके जो एक ही वर्ग का उपयोग करता है जो समान चर का उपयोग करता है)।

सिंक्रनाइज़ किए गए कीवर्ड का उपयोग कोड के ब्लॉक को परिभाषित करने के लिए किया जाता है जहां एकाधिक थ्रेड एक ही चर को एक सुरक्षित तरीके से एक्सेस कर सकते हैं।

और गहरा

synchronized कीवर्ड synchronized कीवर्ड को Object लेता है क्योंकि यह पैरामीटर ( लॉक ऑब्जेक्ट कहा जाता है ), जिसके बाद { block of code }

  • जब निष्पादन इस कीवर्ड से मुकाबला करता है, तो वर्तमान धागा लॉक ऑब्जेक्ट को लॉक ऑब्जेक्ट को लॉक ऑब्जेक्ट को लॉक ऑब्जेक्ट को लॉक ऑब्जेक्ट (लॉक / अधिग्रहण / अपना "लेना) और कोड के संबंधित ब्लॉक को निष्पादित करने का प्रयास करता है।

  • सिंक्रनाइज़ कोड ब्लॉक के अंदर चर के लिए कोई भी लिखने वाले प्रत्येक अन्य थ्रेड के लिए दृश्यमान होने की गारंटी दी जाती है जो समान लॉक ऑब्जेक्ट का उपयोग करके एक सिंक्रनाइज़ कोड ब्लॉक के अंदर कोड निष्पादित करता है।

  • एक समय में केवल एक धागा ताला पकड़ सकता है, जिसके दौरान सभी अन्य धागे एक ही लॉक ऑब्जेक्ट को प्राप्त करने का प्रयास कर रहे हैं (उनके निष्पादन को रोकें)। निष्पादन सिंक्रनाइज़ कोड ब्लॉक से बाहर निकलने पर लॉक जारी किया जाएगा।

सिंक्रनाइज़ किए गए तरीके:

एक विधि परिभाषा में synchronized कीवर्ड को जोड़ने से पूरे विधि निकाय के बराबर एक सिंक्रनाइज़ कोड ब्लॉक में लपेटा जा रहा है, जिसमें लॉक ऑब्जेक्ट (उदाहरण के तरीकों के लिए) और ClassInQuestion.getClass() (क्लास विधियों के लिए) है

- इंस्टेंस विधि एक विधि है जिसमें static कीवर्ड नहीं है।
- कक्षा विधि एक विधि है जिसमें static कीवर्ड है।

तकनीकी

सिंक्रनाइज़ेशन के बिना, यह गारंटी नहीं दी जाती है कि कौन से क्रम पढ़ते हैं और लिखते हैं, संभवतः चर को कचरे के साथ छोड़कर।
(उदाहरण के लिए एक चर एक थ्रेड द्वारा लिखे गए बिट्स के आधा और दूसरे थ्रेड द्वारा लिखे गए बिट्स के आधा भाग के साथ समाप्त हो सकता है, जिससे वे एक राज्य में परिवर्तनीय को छोड़ देते हैं कि धागे में से कोई भी लिखने की कोशिश नहीं करता है, लेकिन दोनों की एक संयुक्त गड़बड़ी है।)

एक थ्रेड में एक लिखने के ऑपरेशन को पूरा करने के लिए पर्याप्त नहीं है (दीवार घड़ी का समय) एक और थ्रेड इसे पढ़ता है, क्योंकि हार्डवेयर चर के मूल्य को कैश कर सकता था, और रीडिंग थ्रेड को लिखे गए चीज़ों के बजाय कैश किए गए मान को देखेंगे यह।

निष्कर्ष

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

सूत्रों का कहना है

http://docs.oracle.com/javase/specs/jls/se8/html/index.html
जावा® भाषा विशिष्टता, 2015-02-13


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


खैर, मुझे लगता है कि हमारे पास पर्याप्त सैद्धांतिक स्पष्टीकरण थे, इसलिए इस कोड पर विचार करें

public class SOP {
    public static void print(String s) {
        System.out.println(s+"\n");
    }
}

public class TestThread extends Thread {
    String name;
    TheDemo theDemo;
    public TestThread(String name,TheDemo theDemo) {
        this.theDemo = theDemo;
        this.name = name;
        start();
    }
    @Override
    public void run() {
        theDemo.test(name);
    }
}

public class TheDemo {
    public synchronized void test(String name) {
        for(int i=0;i<10;i++) {
            SOP.print(name + " :: "+i);
            try{
                Thread.sleep(500);
            } catch (Exception e) {
                SOP.print(e.getMessage());
            }
        }
    }
    public static void main(String[] args) {
        TheDemo theDemo = new TheDemo();
        new TestThread("THREAD 1",theDemo);
        new TestThread("THREAD 2",theDemo);
        new TestThread("THREAD 3",theDemo);
    }
}

नोट: जब तक पिछले थ्रेड के निष्पादन समाप्त नहीं हो जाते हैं, तब तक अगली थ्रेड की कॉल विधि परीक्षण () को synchronized जाता है। थ्रेड इस विधि को एक समय में एक्सेस कर सकते हैं। synchronized बिना सभी धागे इस विधि को एक साथ एक्सेस कर सकते हैं।

जब कोई थ्रेड ऑब्जेक्ट की सिंक्रनाइज़ विधि 'टेस्ट' कहता है (यहां ऑब्जेक्ट 'द डेमो' क्लास का एक उदाहरण है) यह उस ऑब्जेक्ट के लॉक को प्राप्त करता है, तो कोई भी नया थ्रेड उसी ऑब्जेक्ट की किसी सिंक्रनाइज़ विधि को तब तक कॉल नहीं कर सकता जब तक कि पिछले थ्रेड जो लॉक हासिल कर लिया था लॉक जारी नहीं करता है।

इसी तरह की चीज होती है जब कक्षा की किसी भी स्थिर सिंक्रनाइज़ विधि को बुलाया जाता है। थ्रेड कक्षा से जुड़े लॉक को प्राप्त करता है (इस मामले में उस वर्ग के किसी उदाहरण के किसी भी गैर स्थैतिक सिंक्रनाइज़ विधि को किसी थ्रेड द्वारा बुलाया जा सकता है क्योंकि वह ऑब्जेक्ट लेवल लॉक अभी भी उपलब्ध है)। कोई भी अन्य धागा कक्षा के किसी स्थिर सिंक्रनाइज़ विधि को तब तक कॉल करने में सक्षम नहीं होगा जब तक क्लास लेवल लॉक थ्रेड द्वारा जारी नहीं किया जाता है जो वर्तमान में लॉक रखता है।

सिंक्रनाइज़ के साथ आउटपुट

THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9

सिंक्रनाइज़ किए बिना आउटपुट

THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9

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

class MyRunnable implements Runnable {
    int var = 10;
    @Override
    public void run() {
        call();
    }

    public void call() {
        synchronized (this) {
            for (int i = 0; i < 4; i++) {
                var++;
                System.out.println("Current Thread " + Thread.currentThread().getName() + " var value "+var);
            }
        }
    }
}

public class MutlipleThreadsRunnable {
    public static void main(String[] args) {
        MyRunnable runnable1 = new MyRunnable();
        MyRunnable runnable2 = new MyRunnable();
        Thread t1 = new Thread(runnable1);
        t1.setName("Thread -1");
        Thread t2 = new Thread(runnable2);
        t2.setName("Thread -2");
        Thread t3 = new Thread(runnable1);
        t3.setName("Thread -3");
        t1.start();
        t2.start();
        t3.start();
    }
}

हमने दो MyRunnable क्लास ऑब्जेक्ट्स बनाए हैं, runnable1 को थ्रेड 1 और थ्रेड 3 और रननेबल 2 के साथ साझा किया जा रहा है केवल थ्रेड 2 के साथ साझा किया जा रहा है। अब जब टी 1 और टी 3 सिंक्रनाइज़ किए बिना सिंक्रनाइज़ किए जाते हैं, तो पीएफबी आउटपुट जो सुझाव देता है कि थ्रेड 1 और 3 दोनों एक साथ विभिन्न मान को प्रभावित करते हैं जहां थ्रेड 2 के लिए, var की अपनी याददाश्त होती है।

Without Synchronized keyword

    Current Thread Thread -1 var value 11
    Current Thread Thread -2 var value 11
    Current Thread Thread -2 var value 12
    Current Thread Thread -2 var value 13
    Current Thread Thread -2 var value 14
    Current Thread Thread -1 var value 12
    Current Thread Thread -3 var value 13
    Current Thread Thread -3 var value 15
    Current Thread Thread -1 var value 14
    Current Thread Thread -1 var value 17
    Current Thread Thread -3 var value 16
    Current Thread Thread -3 var value 18

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

Current Thread Thread -1 var value 11
Current Thread Thread -2 var value 11
Current Thread Thread -1 var value 12
Current Thread Thread -2 var value 12
Current Thread Thread -1 var value 13
Current Thread Thread -2 var value 13
Current Thread Thread -1 var value 14
Current Thread Thread -2 var value 14
Current Thread Thread -3 var value 15
Current Thread Thread -3 var value 16
Current Thread Thread -3 var value 17
Current Thread Thread -3 var value 18

सिंक्रनाइज़ किए गए मेरी समझ के लिए मूल रूप से मतलब है कि संकलक आपकी विधि के चारों ओर एक monitor.enter और monitor.exit लिखता है। इस तरह यह थ्रेड सुरक्षित हो सकता है कि इसका उपयोग कैसे किया जाता है (मेरा मतलब है कि आप सिंक्रनाइज़ किए गए तरीकों के साथ एक ऑब्जेक्ट लिख सकते हैं जो आपकी कक्षा के आधार पर थ्रेडसेफ नहीं है)।


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

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

Object.wait()

Synchronized normal method Synchronized statement समतुल्य (इस का उपयोग करें)

class A {
    public synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(this) {
             // all function code
        }
    } 
}

Synchronized static method Synchronized statement बराबर (वर्ग का उपयोग करें)

class A {
    public static synchronized void methodA() {
        // all function code
    }

    equivalent to

    public void methodA() {
        synchronized(A.class) {
             // all function code
        }
    } 
}

सिंक्रनाइज़ कथन (चर का उपयोग कर)

class A {
    private Object lock1 = new Object();

    public void methodA() {
        synchronized(lock1 ) {
             // all function code
        }
    } 
}

synchronized , हमारे पास Synchronized Methods और Synchronized Statements दोनों हैं। हालांकि, Synchronized Methods Synchronized Statements समान हैं, इसलिए हमें Synchronized Statements को समझने की आवश्यकता है।

=> असल में, हमारे पास होगा

synchronized(object or class) { // object/class use to provides the intrinsic lock
   // code 
}

यहां 2 लगता है कि synchronized करने में मदद करें

  • प्रत्येक ऑब्जेक्ट / क्लास के साथ एक intrinsic lock होता है।
  • जब कोई थ्रेड एक synchronized statement आह्वान करता है, तो यह स्वचालित intrinsic lock से उस synchronized statement's ऑब्जेक्ट के लिए intrinsic lock प्राप्त करता है और विधि लौटने पर इसे रिलीज़ करता है। जब तक एक थ्रेड एक intrinsic lock का मालिक होता है, तब तक कोई अन्य थ्रेड समान लॉक => थ्रेड सुरक्षित नहीं प्राप्त कर सकता है।

=> जब कोई thread A synchronized(this){// code 1} => सभी ब्लॉक कोड (कक्षा के अंदर) जहां synchronized(this) और सभी synchronized normal method (कक्षा के अंदर) लॉक है क्योंकि समान लॉक है। यह thread A अनलॉक ("// कोड 1" समाप्त होने के बाद निष्पादित होगा)।

यह व्यवहार synchronized(a variable){// code 1} या synchronized(class)

समान LOCK => लॉक (किस विधि पर निर्भर नहीं है? या कौन से बयान?)

सिंक्रनाइज़ विधि या सिंक्रनाइज़ कथन का प्रयोग करें?

मैं synchronized statements पसंद करता हूं क्योंकि यह अधिक विस्तार योग्य है। उदाहरण, भविष्य में, आपको केवल विधि के एक हिस्से को सिंक्रनाइज़ करने की आवश्यकता है। उदाहरण, आपके पास 2 सिंक्रनाइज़ विधि हैं और इसमें एक दूसरे के लिए कोई प्रासंगिक नहीं है , हालांकि जब कोई थ्रेड एक विधि चलाता है, तो यह अन्य विधि को अवरुद्ध कर देगा (यह synchronized(a variable) उपयोग करके रोक सकता है)।

हालांकि, सिंक्रनाइज़ विधि लागू करें सरल है और कोड सरल दिखता है। कुछ वर्ग के लिए, कक्षा में केवल 1 सिंक्रनाइज़ विधि, या कक्षा में सभी सिंक्रनाइज़ विधियां एक दूसरे के लिए प्रासंगिक => हम कोड को छोटा और समझने में आसान बनाने के लिए synchronized method का उपयोग कर सकते हैं

ध्यान दें

(यह synchronized करने के लिए बहुत प्रासंगिक नहीं है, यह ऑब्जेक्ट और क्लास या कोई स्थैतिक और स्थैतिक के बीच अलग नहीं है)।

  • जब आप synchronized या सामान्य विधि या synchronized(this) या synchronized(non-static variable) यह प्रत्येक ऑब्जेक्ट उदाहरण पर आधार सिंक्रनाइज़ करेगा।
  • जब आप synchronized या स्थैतिक विधि या synchronized(class) या synchronized(static variable) यह कक्षा पर आधार सिंक्रनाइज़ करेगा

संदर्भ

effects page

उम्मीद है कि यह मदद करता है


synchronized कीवर्ड कई थ्रेड द्वारा कोड या ऑब्जेक्ट के ब्लॉक पर समवर्ती पहुंच को रोकता है। डिफ़ॉल्ट रूप से, Hashtable synchronized , इसलिए एक ही समय में केवल एक थ्रेड तालिका तक पहुंच सकता है।

HashMap जैसे non-synchronized संरचनाओं के उपयोग पर, आपको स्मृति स्थिरता त्रुटियों को रोकने के लिए अपने कोड में थ्रेड सुरक्षा सुविधाओं का निर्माण करना होगा।


synchronized कीवर्ड विधि को दर्ज करते समय एक थ्रेड को लॉक प्राप्त करने का कारण बनता है, ताकि केवल एक ही थ्रेड एक ही समय में विधि को निष्पादित कर सके (दिए गए ऑब्जेक्ट उदाहरण के लिए, जब तक यह एक स्थिर विधि न हो)।

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

इस पर विचार करो:

 if (vector.isEmpty()){
     vector.add(data);
 }

भले ही शामिल विधियों को सिंक्रनाइज़ किया गया हो, क्योंकि वे अलग-अलग लॉक और अनलॉक किए जा रहे हैं, दो दुर्भाग्य से समय वाले धागे दो तत्वों के साथ वेक्टर बना सकते हैं।

तो असल में, आपको अपने एप्लिकेशन कोड में सिंक्रनाइज़ करना होगा।

चूंकि विधि-स्तर सिंक्रनाइज़ेशन ए) महंगी होती है जब आपको इसकी आवश्यकता नहीं होती है और बी) जब आपको सिंक्रनाइज़ेशन की आवश्यकता होती है तो अपर्याप्त, अब अन-सिंक्रनाइज़ प्रतिस्थापन (वेक्टर के मामले में ऐरेलिस्ट) हैं।

हाल ही में, समेकन पैकेज जारी किए गए हैं, कई चालाक उपयोगिताएं जो बहु-थ्रेडिंग समस्याओं का ख्याल रखती हैं।







synchronized