إذا تعذرت مزامنة الوصول إلى البيانات المشتركة القابلة للتغيير، فقد تكون العواقب وخيمة، حتى لو كان المتغير قابلاً للقراءة والكتابة ذريًا.
دعونا نفكر في مشكلة مزامنة الخيط. لمزامنة سلسلة المحادثات، توفر مكتبة فئة Java طريقة Thread.stop، لكن هذه الطريقة لا تستحق الترويج لأنها غير آمنة بطبيعتها. سيكون من الأفضل استخدام الاقتراع، مثل البرنامج التالي.
انسخ رمز الكود كما يلي:
import java.util.concurrent.TimeUnit;
فئة عامة StopThread {
/**
* @param args
*/
تم طلب إيقاف منطقي ثابت خاص؛
الفراغ العام الثابت الرئيسي (String[] args)
يرمي InterruptedException {
خلفية الموضوع = موضوع جديد (جديد Runnable () {
@تجاوز
تشغيل الفراغ العام () {
كثافة العمليات ط = 0؛
بينما(!stopRequested){
أنا++;
System.out.println(i);
}
}
});
خلفيةThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}
قد تعتقد أنه بعد تشغيل هذا البرنامج لمدة ثانية واحدة تقريبًا، يقوم الخيط الرئيسي بتعيين stopRequested على "صحيح"، مما يتسبب في توقف الخيط الجديد في الخلفية. في الواقع، هذا ليس هو الحال، لأن مؤشر الترابط في الخلفية لا يمكنه رؤية التغيير في هذا القيمة، لذلك ستستمر في التكرار إلى ما لا نهاية، وهذا هو نتيجة عدم مزامنة البيانات. لذلك دعونا نفعل هذا بشكل متزامن.
انسخ رمز الكود كما يلي:
import java.util.concurrent.TimeUnit;
فئة عامة StopThread {
/**
* @param args
*/
تم طلب إيقاف منطقي ثابت خاص؛
طلب باطلة متزامنة ثابتة خاصةStop(){
stopRequested = true;
}
stopRequested المنطقية المتزامنة الثابتة الخاصة (){
طلب إيقاف العودة؛
}
الفراغ العام الثابت الرئيسي (String[] args)
يرمي InterruptedException {
خلفية الموضوع = موضوع جديد (جديد Runnable () {
@تجاوز
تشغيل الفراغ العام () {
كثافة العمليات ط = 0؛
بينما(!stopRequested()){
أنا++;
System.out.println(i);
}
}
});
خلفيةThread.start();
TimeUnit.SECONDS.sleep(1);
requestStop();
}
}
يؤدي هذا إلى تحقيق مزامنة البيانات. تجدر الإشارة إلى أن كلاً من طريقة الكتابة (requestStop) وطريقة القراءة (stopRequested) بحاجة إلى المزامنة، وإلا فلن تتم مزامنتهما بالمعنى الحقيقي.
بالإضافة إلى ذلك، يمكننا استخدام معدل المتغير المتغير لإكمال مهام المزامنة بشكل أكثر بساطة.
انسخ رمز الكود كما يلي:
import java.util.concurrent.TimeUnit;
فئة عامة StopThread {
/**
* @param args
*/
مطلوب توقف منطقي متقلب خاص؛
الفراغ العام الثابت الرئيسي (String[] args)
يرمي InterruptedException {
خلفية الموضوع = موضوع جديد (جديد Runnable () {
@تجاوز
تشغيل الفراغ العام () {
كثافة العمليات ط = 0؛
بينما(!stopRequested){
أنا++;
System.out.println(i);
}
}
});
خلفيةThread.start();
TimeUnit.SECONDS.sleep(1);
stopRequested = true;
}
}