في برمجة جافا متعددة الخيوط ، غالبًا ما يتم العثور على تقلبات. في بعض الأحيان يتم الخلط بين هذه الكلمة الرئيسية مع متزامن أو قفل. التحليل المحدد هو كما يلي:
في بيئة متعددة الخيوط ، ستكون هناك مشكلة في رؤية متغيرات الأعضاء: يحتوي كل مؤشر ترابط في Java على مساحة ذاكرة لمكدس مؤشر ترابط ، مما يحفظ المعلومات المتغيرة للمعلومات عند تشغيلها. عندما يصل مؤشر ترابط إلى قيمة متغيرة معينة ، سيجد أولاً ذاكرة كومة الكائن أو المحتوى المحدد للمكدس (نوع البيانات الأصلي) استنادًا إلى عنوان المتغير ، ثم حفظ نفس نسخة القيمة في مكدس مؤشر الترابط هذا. بعد ذلك ، لا علاقة لجميع العمليات على هذا المتغير بالمحتوى المتغير في المكدس قبل خروج مؤشر الترابط. تعمل على النسخة في مكدس الخيط. بعد اكتمال العملية ، سيتم كتابة نتيجة العملية إلى الذاكرة الرئيسية. إذا كان هناك خيطان A و B ، ويقوم الزملاء بتشغيل متغير معين X ؛ يضيف A 1 إلى X ، ثم قد تكون النسخة التي تم الحصول عليها بواسطة B نتيجة X Plus 1 أو X ؛ للتأكد من أن هناك حاجة إلى أحدث متغير بيانات في الذاكرة لإضافة الكلمة الرئيسية المتطايرة ، لذلك في كل مرة تعمل فيها على X ، ستتحقق مما إذا كانت قيمة المتغير في مكدس مؤشر الترابط هي نفس قيمة المتغير في الذاكرة ، وإذا كانت مختلفة ، فسيتم تحميلها مرة أخرى.
على سبيل المثال:
سيؤدي Thownsee من الفئة العامة {// أن يقوم مؤشر ترابط T1 بإجراء العمليات المقابلة استنادًا إلى قيمة العلامة ، وسوف يغير مؤشر الترابط الرئيسي قيمة T1 Public Static Void Main (String [] args) interruptedException {threadtest th = new threadtest () ؛ الموضوع T1 = موضوع جديد (TH) ؛ t1.start () ؛ thread.sleep (1000) ؛ th.ChangeFlag () ؛ thread.sleep (2000) ؛ System.out.println (th.getFlag ()) ؛ }} class threadtest referements {// عندما يقوم مؤشر ترابط بالوصول إلى متغير ، فسيقوم بتحميله في مكدس مؤشر الترابط المقابل. في كل عملية ، يجب أن تحصل على أحدث البيانات في الذاكرة الخاصة بملاجئ Boolean Stopflag ؛ Override public void run () {int i = 0 ؛ بينما (! stopflag) {i ++ ؛ System.out.println ("=="+thread.currentThRead (). getName ()) ؛ } system.out.println ("thread finish:"+i) ؛ } public void changeflag () {this.stopflag = true ؛ System.out.println (thread.currentThRead (). getName ()+"*********") ؛ } public boolean getFlag () {return stopflag ؛ }} إذا تمت إزالة الرمز أعلاه ، فسيستمر تنفيذها في حلقة ميتة.
لكن لا يمكن أن يضمن التزامن آمن مؤشر الترابط
على سبيل المثال:
تقوم Threadsave العامة بتنفيذ Runnable {static threadsave sync = new threadsave () ؛ ثابت متقلبة int j = 0 ؛ // lock lock = new reentrantlock () ؛ public void inscane () {// lock.lock () ؛ لـ (int i = 0 ؛ i <10000000 ؛ i ++) {j ++ ؛ } // lock.unlock () ؛ } Override public void run () {inscane () ؛ } rems static void main (string [] args) remrows interruptedException {thread t1 = new thread (sync) ؛ الموضوع T2 = مؤشر ترابط جديد (Sync) ؛ t1.start () ؛ t2.start () ؛ t1.join () ؛ t2.join () ؛ system.out.println (j) ؛ }} ليس من المتوقع أن تكون نتيجة التنفيذ وفقًا للرمز أعلاه 20000000 ،
لأنه بالنسبة للمتغيرات التي تم تعديلها بواسطة متقلبة ، فإن الجهاز الظاهري JVM يضمن فقط أن القيمة المحملة من الذاكرة الرئيسية إلى ذاكرة العمل هي الأحدث.
على سبيل المثال ، إذا كان مؤشر الترابط 1 و Prohet 2 يقومان بإجراء مكدس مؤشر ترابط وعمليات قراءة الذاكرة الرئيسية وتحميله ، وابحث عن أن قيمة العد في الذاكرة الرئيسية هي 5 ، فسيتم تحميل أحدث قيمة. بعد تعديل عدد الخيط 1 كومة ، سيتم كتابته في الذاكرة الرئيسية ، وسيصبح متغير العد في الذاكرة الرئيسية 6 ؛
نظرًا لأن Thread 2 قام بالفعل بإجراء عمليات القراءة والتحميل ، بعد إجراء العملية ، سيتم أيضًا تحديث القيمة المتغيرة لعدد الذاكرة الرئيسي إلى 6 ؛
يؤدي هذا إلى حدوث التزامن بعد تعديل خيطين مع الكلمة الرئيسية المتطايرة في الوقت المناسب.
في ملخص:
سيؤكد المتقلبة فقط أن يقوم مؤشر الترابط بإجراء يتحقق مما إذا كانت القيمة المتغيرة لمكدس مؤشر الترابط الحالي هي نفس قيمة البيانات في الذاكرة الرئيسية ، وهذا كل شيء. سيضمن القفل أو المزامنة أن مؤشر ترابط واحد فقط يدخل الطريقة في لحظة معينة ، وبالتالي ضمان سلامة مؤشر الترابط.
لذلك إذا قامت مؤشرات ترابط متعددة بتعديل متغير متطاير ، فلا يوجد معنى منطقي فعلي. إذا قام مؤشر ترابط بتعديل القيمة المتغيرة للمواضيع الأخرى التي تعتمد على التعديل ، فسيكون ذلك مفيدًا في هذا الوقت.
ما سبق هو كل شيء عن هذا المقال ، آمل أن يكون مفيدًا لتعلم الجميع.