"हॅलो, अमिगो! काल आम्ही मल्टीथ्रेडिंगचे फायदे आणि सुविधांबद्दल चर्चा केली. आता तोटे पाहण्याची वेळ आली आहे. आणि दुर्दैवाने, ते लहान नाहीत."

पूर्वी, आम्ही एकमेकांच्या पद्धतींना कॉल करणार्‍या वस्तूंचा संच म्हणून प्रोग्रामकडे पाहिले. आता सर्वकाही थोडे अधिक क्लिष्ट होते. प्रोग्राम हा ऑब्जेक्ट्सच्या संचासारखा असतो ज्यामध्ये अनेक "छोटे रोबोट्स" (थ्रेड्स) असतात ज्याद्वारे ते रेंगाळतात आणि पद्धतींमध्ये असलेल्या कमांड्सची अंमलबजावणी करतात.

हा नवीन अर्थ पहिला रद्द करत नाही. ते अजूनही वस्तू आहेत आणि तरीही ते एकमेकांच्या पद्धतींना कॉल करतात. परंतु आपण हे लक्षात ठेवले पाहिजे की अनेक धागे आहेत आणि प्रत्येक धागा स्वतःचे कार्य किंवा कार्य करतो.

एक कार्यक्रम अधिक क्लिष्ट होत आहे. वेगवेगळे थ्रेड्स ते करत असलेल्या कार्यांच्या आधारावर वेगवेगळ्या वस्तूंची स्थिती बदलतात. आणि ते एकमेकांच्या बोटांवर पाऊल ठेवू शकतात.

पण सर्वात वाईट गोष्ट जावा मशीनमध्ये खोलवर घडते. मी आधीच म्हटल्याप्रमाणे, थ्रेड्सची स्पष्ट एकसमानता या वस्तुस्थितीद्वारे प्राप्त होते की प्रोसेसर सतत एका थ्रेडवरून दुसर्‍या थ्रेडवर स्विच करतो. ते एका थ्रेडवर स्विच करते, 10 मिलीसेकंदांसाठी काम करते, पुढील थ्रेडवर स्विच करते, 10 मिलीसेकंदांसाठी काम करते, आणि असेच. आणि येथेच समस्या आहे: हे स्विच सर्वात अयोग्य क्षणी येऊ शकतात. या उदाहरणाचा विचार करा:

पहिल्या धाग्याचा कोड दुसऱ्या धाग्याचा कोड
System.out.print ("Nick is");
System.out.print ("");
System.out.print ("15");
System.out.print ("");
System.out.print ("years old");
System.out.println ();
System.out.print ("Lena is");
System.out.print ("");
System.out.print ("21");
System.out.print ("");
System.out.print ("years old");
System.out.println ();
आम्ही जे प्रदर्शित करणे अपेक्षित आहे
निक 15 वर्षांचा आहे
लीना 21 वर्षांची आहे
वास्तविक कोड अंमलबजावणी पहिल्या धाग्याचा कोड दुसऱ्या धाग्याचा कोड
System.out.print ("Nick is");
System.out.print ("Lena is");
System.out.print (" ");
System.out.print (" ");
System.out.print ("15");
System.out.print ("21");
System.out.print (" ");
System.out.print (" ");
System.out.print ("years old");
System.out.println ();
System.out.print ("years old");
System.out.println ();
System.out.print ("Nick is");
//other thread is running
//other thread is running
System.out.print (" ");
System.out.print ("15");
//other thread is running
//other thread is running
System.out.print (" ");
System.out.print ("years old");
System.out.println ();
//other thread is running
//other thread is running
//other thread is running
System.out.print ("Lena is");
System.out.print (" ");
//other thread is running
//other thread is running
System.out.print ("21");
System.out.print (" ");
//other thread is running
//other thread is running
//other thread is running
System.out.print ("years old");
System.out.println ();
प्रत्यक्षात काय दाखवले जाते
निक म्हणजे  लीना   15  21  वर्षांची
आहे

आणि येथे आणखी एक उदाहरण आहे:

कोड वर्णन
class MyClass
{
private String name1 = "Ally";
private String name2 = "Lena";
public void swap()
{
String s = name1;
name1 = name2;
name2 = s;
}
}
स्वॅप पद्धत आणि व्हेरिएबल्सची swapमूल्ये .name1name2

एकाच वेळी दोन थ्रेड्सवरून कॉल केल्यास काय होऊ शकते?

वास्तविक कोड अंमलबजावणी पहिल्या धाग्याचा कोड दुसऱ्या धाग्याचा कोड
String s1 = name1; //Ally
name1 = name2; //Lena
String s2 = name1; //Lena(!)
name1 = name2; //Lena
name2 = s1; //Ally
name2 = s2; //Lena
String s1 = name1;
name1 = name2;
//other thread is running
//other thread is running
name2 = s1;
//other thread is running
//other thread is running
//other thread is running
String s2 = name1;
name1 = name2;
//other thread is running
name2 = s2;
तळ ओळ
दोन्ही व्हेरिएबल्समध्ये "लेना" मूल्य आहे.
"सहयोगी" ऑब्जेक्टने ते केले नाही. तो हरवला आहे.

"एवढ्या सोप्या असाइनमेंट ऑपरेशनमध्ये अशा त्रुटी शक्य आहेत याचा अंदाज कोणी लावला असेल?!"

"हो, या समस्येवर उपाय आहे. पण आपण याबद्दल थोड्या वेळाने बोलू - माझा घसा कोरडा आहे."