"हॅलो, अमिगो! तुम्हाला आठवत असेल की एलीने तुम्हाला अनेक थ्रेड्स एकाच वेळी शेअर केलेल्या संसाधनात प्रवेश करण्याचा प्रयत्न करतात तेव्हा उद्भवणाऱ्या समस्यांबद्दल सांगितले होते, होय?"

"हो."

"गोष्ट एवढंच नाहीये. अजून एक छोटी समस्या आहे."

तुम्हाला माहिती आहेच की, कॉम्प्युटरमध्ये मेमरी असते जिथे डेटा आणि कमांड (कोड) साठवले जातात, तसेच प्रोसेसर जो या कमांड्सची अंमलबजावणी करतो आणि डेटासह कार्य करतो. प्रोसेसर मेमरीमधील डेटा वाचतो, तो बदलतो आणि मेमरीमध्ये परत लिहितो. गणना वेगवान करण्यासाठी, प्रोसेसरची स्वतःची अंगभूत "जलद" मेमरी आहे: कॅशे.

प्रोसेसर त्याच्या कॅशेमध्ये वारंवार वापरले जाणारे व्हेरिएबल्स आणि मेमरीचे क्षेत्र कॉपी करून जलद चालतो. मग ते या जलद मेमरीमध्ये सर्व बदल करते. आणि मग ते डेटा परत «स्लो» मेमरीवर कॉपी करते. हे सर्व असताना, स्लो मेमरीमध्ये जुने (अपरिवर्तित!) व्हेरिएबल्स असतात.

इथेच ही समस्या निर्माण होते. एक थ्रेड व्हेरिएबल बदलतो , जसे की वरील उदाहरणात isCancel किंवा isInterrupted, परंतु दुसरा थ्रेड «हा बदल पाहत नाही , कारण तो जलद मेमरीमध्ये झाला आहे. थ्रेड्सना एकमेकांच्या कॅशेमध्ये प्रवेश नसल्याचा हा परिणाम आहे. (प्रोसेसरमध्ये बर्‍याचदा अनेक स्वतंत्र कोर असतात आणि थ्रेड भौतिकदृष्ट्या भिन्न कोरांवर चालू शकतात.)

कालचे उदाहरण आठवूया:

कोड वर्णन
class Clock implements Runnable
{
private boolean isCancel = false;

public void cancel()
{
this.isCancel = true;
}

public void run()
{
while (!this.isCancel)
{
Thread.sleep(1000);
System.out.println("Tick");
}
}
}
धागा "माहित नाही" की इतर धागे अस्तित्वात आहेत.

रन पद्धतीमध्ये, isCancel व्हेरिएबल चाइल्ड थ्रेडच्या कॅशेमध्ये टाकले जाते जेव्हा ते पहिल्यांदा वापरले जाते. हे ऑपरेशन खालील कोडच्या समतुल्य आहे:

public void run()
{
boolean isCancelCached = this.isCancel;
while (!isCancelCached)
{
Thread.sleep(1000);
System.out.println("Tick");
}
}

दुसर्‍या थ्रेडवरून रद्द करण्याची पद्धत कॉल केल्याने isCancel चे मूल्य सामान्य (स्लो) मेमरीमध्ये बदलेल , परंतु इतर थ्रेडच्या कॅशेमध्ये नाही.

public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
clock.cancel();
}

"अरेरे! आणि त्यांनी यासाठीही एक सुंदर उपाय शोधून काढला, जसे की  सिंक्रोनाइझ्ड ?"

"तुझा विश्वास बसणार नाही!"

पहिला विचार कॅशे अक्षम करण्याचा होता, परंतु यामुळे प्रोग्राम अनेक वेळा हळू चालतात. मग वेगळाच उपाय निघाला.

अस्थिर कीवर्डचा जन्म झाला . आम्ही हा कीवर्ड व्हेरिएबल डिक्लेरेशनच्या आधी ठेवतो हे सूचित करण्यासाठी की त्याचे मूल्य कॅशेमध्ये ठेवले जाऊ नये. अधिक तंतोतंत, असे नाही की ते कॅशेमध्ये ठेवले जाऊ शकत नाही, ते नेहमी सामान्य (मंद) मेमरीमधून वाचले आणि लिहावे लागते.

आमचे निराकरण कसे करायचे ते येथे आहे जेणेकरून सर्व काही ठीक होईल:

कोड वर्णन
class Clock implements Runnable
{
private volatile boolean isCancel = false;

public void cancel()
{
this.isCancel = true;
}

public void run()
{
while (!this.isCancel)
{
Thread.sleep(1000);
System.out.println("Tick");
}
}
}
अस्थिर सुधारक सर्व थ्रेड्सद्वारे सामायिक केलेल्या सामान्य मेमरीमधून नेहमी वाचले आणि लिहिलेले व्हेरिएबल बनवते.
public static void main(String[] args)
{
Clock clock = new Clock();
Thread clockThread = new Thread(clock);
clockThread.start();

Thread.sleep(10000);
clock.cancel();
}

"बस एवढेच?"

"तेच. साधे आणि सुंदर."