"नमस्कार, अमीगो! हमारे पास एक रामबाण औषधि है—सभी बीमारियों का इलाज। जैसा कि हमने पहले ही देखा है, अनियंत्रित थ्रेड स्विचिंग एक समस्या है।"

"क्यों थ्रेड स्वयं यह तय नहीं कर सकते कि अगले थ्रेड पर कब स्विच करना है? वे सब कुछ करें जो उन्हें करने की आवश्यकता है और फिर संकेत दें, «मेरा काम हो गया!»?"

"स्विचिंग को नियंत्रित करने के लिए थ्रेड्स को अनुमति देना और भी बड़ी समस्या होगी। मान लीजिए कि आपके पास कुछ खराब लिखा हुआ कोड है, और थ्रेड कभी भी सीपीयू को सरेंडर नहीं करता है। दिन में वापस, यह इस तरह काम करता था। और यह काफी बुरा सपना था।"

"ठीक है। तो क्या उपाय है?"

" अन्य थ्रेड्स को ब्लॉक करना।  यह इस तरह काम करता है।"

यह स्पष्ट हो गया कि थ्रेड्स एक दूसरे के साथ हस्तक्षेप करते हैं जब वे साझा वस्तुओं और/या संसाधनों का उपयोग करने का प्रयास करते हैं । जैसा कि हमने उदाहरण में कंसोल आउटपुट के साथ देखा: इसमें एक कंसोल और सभी थ्रेड आउटपुट हैं। यह गन्दा है।

इसलिए एक विशेष वस्तु का आविष्कार किया गया: म्यूटेक्स । यह एक बाथरूम के दरवाजे पर एक संकेत की तरह है जो कहता है «उपलब्ध / कब्जा» । इसकी दो अवस्थाएँ होती हैं: वस्तु उपलब्ध है या व्याप्त है । इन राज्यों को "लॉक" और "अनलॉक" भी कहा जाता है।

जब किसी थ्रेड को किसी ऑब्जेक्ट को अन्य थ्रेड्स के साथ साझा करने की आवश्यकता होती है, तो वह ऑब्जेक्ट से जुड़े म्यूटेक्स की जांच करता है। यदि म्यूटेक्स अनलॉक हो जाता है, तो थ्रेड इसे लॉक कर देता है (इसे «अधिकृत» के रूप में चिह्नित करता है) और साझा संसाधन का उपयोग करना शुरू कर देता है। थ्रेड द्वारा अपना व्यवसाय पूरा करने के बाद, म्यूटेक्स अनलॉक हो जाता है ("उपलब्ध" के रूप में चिह्नित)।

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

"तो मैं एक म्यूटेक्स के साथ कैसे काम करूं? क्या मुझे विशेष ऑब्जेक्ट बनाने की ज़रूरत है?"

"यह उससे बहुत सरल है। जावा के रचनाकारों ने इस म्यूटेक्स को ऑब्जेक्ट क्लास में बनाया है। इसलिए आपको इसे बनाना भी नहीं है। यह हर वस्तु का हिस्सा है। यहां बताया गया है कि यह कैसे काम करता है:"

कोड विवरण
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}
}
स्वैप विधि नाम 1 और नाम 2 चर के मानों को स्वैप करती है।

क्या हो सकता है अगर इसे एक ही समय में दो धागे से बुलाया जाए?

वास्तविक कोड निष्पादन पहले धागे का कोड दूसरे सूत्र का कोड
String s1 = name1; //Ally
name1 = name2; //Lena
name2 = s1; //Ally

String s2 = name1; //Lena
name1 = name2; //Ally
name2 = s2; //Lena
String s1 = name1;
name1 = name2;
//other thread is running
name2 = s1;
//the thread waits until the mutex is unlocked

String s2 = name1;
name1 = name2;
//other thread is running
//other thread is running
name2 = s2;
तल - रेखा
चर के मूल्यों को दो बार स्वैप किया गया, अपने मूल स्थान पर लौट आया।

सिंक्रनाइज़ किए गए कीवर्ड पर ध्यान दें  ।

"हाँ, इसका क्या मतलब है?"

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

यदि म्यूटेक्स पर कब्जा कर लिया गया है, तो हमारा धागा स्थिर रहेगा और इसके मुक्त होने की प्रतीक्षा करेगा।

"इतना सरल और इतना सुरुचिपूर्ण। यह एक सुंदर समाधान है।"

"हाँ, लेकिन आपको क्या लगता है कि इस मामले में क्या होगा?"

कोड विवरण
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}

public void swap2()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}
}
स्वैप और स्वैप2 विधियां एक ही म्यूटेक्स ( यह ऑब्जेक्ट) साझा करती हैं।

क्या होता है यदि एक थ्रेड स्वैप विधि को कॉल करता है और दूसरा थ्रेड स्वैप2 विधि को कॉल करता है?

"चूंकि म्यूटेक्स समान है, दूसरे थ्रेड को तब तक इंतजार करना होगा जब तक कि पहला थ्रेड सिंक्रोनाइज़्ड ब्लॉक को छोड़ न दे। इसलिए एक साथ एक्सेस करने में कोई समस्या नहीं होगी।"

"शाबाश, अमीगो! यह सही उत्तर है!"

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

कोड वास्तव में क्या होता है
class MyClass
{
private static String name1 = "Ally";
private static String name2 = "Lena";

public synchronized void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}

public static synchronized void swap2()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
class MyClass
{
private static String name1 = "Ally";
private static String name2 = "Lena";

public void swap()
{
synchronized (this)
{
String s = name1;
name1 = name2;
name2 = s;
}
}

public static void swap2()
{
synchronized (MyClass.class)
{
String s = name1;
name1 = name2;
name2 = s;
}
}