1. مقدمة
تسجل هذه المقالة بعض نقاط المعرفة حول آلية المقاطعة في Java MultiThreading. يتكون بشكل أساسي من الفرق بين طريقة الإيقاف ، والطرق المقاطعة () و isInterredred () ، ويقوم بتحليل بسيط من تنفيذ الكود المصدري.
هناك 3 طرق لإنهاء المواضيع الجارية في جافا
① يخرج الخيط عادة ، أي طريقة التشغيل () تم تنفيذها
② استخدم طريقة STOP () في فئة مؤشر الترابط لإنهاء مؤشر الترابط بقوة. ومع ذلك ، انتهت صلاحية طريقة STOP () ولا ينصح باستخدامها
③ استخدام آلية المقاطعة
لا يوجد شيء يجب فعله عندما يخرج الخيط بشكل طبيعي. يتم تقديم آلية المقاطعة بالتفصيل أدناه. دعونا نلقي نظرة أولاً على الكود المصدري لطريقة STOP (). المفتاح هو التعليقات على رمز المصدر. وهذا ما يفسر لماذا STOP () غير آمن ، أي موضوع يتم إيقافه بواسطة طريقة STOP ()؟
/*** يفرض مؤشر ترابط التوقف عن التنفيذ.* <p>* إذا كان هناك مدير أمان تم تثبيته ، يتم استدعاء <code> checkAccess </code>* طريقة </code>* كوسيطة. قد ينتج عن هذا* <code> SecurityException </code> أن يتم رفعه (في مؤشر الترابط الحالي).* <p>* إذا كان هذا الموضوع مختلفًا عن الموضوع الحالي (أي ، يحاول مؤشر الترابط الحالي إيقاف مؤشر ترابط آخر غير نفسه) ، فالرمز الأمني </code) <code> SecurityException </code> (في مؤشر الترابط الحالي).* <p>* يضطر مؤشر الترابط الذي يمثله هذا الموضوع إلى إيقاف أي شيء* يفعله بشكل غير طبيعي ورمي الكائن الذي تم إنشاؤه حديثًا*. <code> ThreadDeath </code> ما لم يكن يجب القيام ببعض عملية التنظيف غير العادية (لاحظ أن رمي* <code> ThreadDeath </code> يسبب <code> أخيرًا </code> بنود* <code> جرب </code> يتم تنفيذ عباراتها قبل أن يتم Dies* رسميًا). إذا كان A <code> catch </code> يمسك بندس* <code> ThreadDeath </code> ، فمن المهم إعادة توحيد الكائن* حتى يموت مؤشر الترابط. لا يمكن* تعديل هذا الموضوع.* see #interrupt ()* see #checkaccess ()* see #run ()* see #start ()* seee threaddeath* seese threadgroup #uncaughtexception (thread ، remable) يؤدي إيقاف مؤشر ترابط مع* thread.stop إلى إلغاء قفل جميع الشاشات التي تم قفلها (كنتيجة طبيعية للرسو* <code> ThreadDeath </code> استثناء نشر المكدس). إذا كانت* أي من الكائنات المحمية مسبقًا من قبل هذه الشاشات كانت في حالة غير متناسقة ، تصبح الكائنات التالفة مرئية لـ* مؤشرات ترابط أخرى ، مما يؤدي إلى سلوك تعسفي. يجب استبدال العديد من استخدامات <code> STOP </code> برمز ببساطة* تعديل بعض المتغيرات للإشارة إلى أن مؤشر ترابط الهدف يجب أن يتوقف عن تشغيله. يجب أن يتحقق مؤشر ترابط الهدف من هذا المتغير* بانتظام ، والعودة من طريقة التشغيل الخاصة به بطريقة منظمة* إذا كان المتغير يشير إلى أنه هو التوقف عن التشغيل. إذا كان مؤشر ترابط الهدف* ينتظر لفترات طويلة (على متغير الحالة ،* على سبيل المثال) ، يجب استخدام طريقة <code> المقاطعة </code> لتقطيع WAIT.* لمزيد من المعلومات ، راجع* <a href = "{@@docroot} /../ technotes/side/concurrency/threadprimitiveprecation.html انخفاض؟ </a>.كما تم التعليق أعلاه ، تشير الأسطر من 9 إلى 16 إلى أن طريقة STOP () يمكن أن تتوقف عن "مؤشرات الترابط الأخرى". يسمى مؤشر الترابط الذي ينفذ طريقة Thread.stop () مؤشر الترابط الحالي ، في حين أن "مؤشر الترابط الآخر" هو مؤشر الترابط الذي يمثله مؤشر ترابط الكائن الذي يستدعي throp.stop () طريقة.
يحب:
الفراغ الثابت العام الرئيسي (سلسلة [] args) {mythread thread = new MyThread ... // .... thread.stop () ؛ // ..}في الطريقة الرئيسية ، الخيط الحالي هو الخيط الرئيسي. ينفذ إلى السطر 4 ويريد إيقاف مؤشر ترابط "الخيط الآخر". هذا الموضوع الآخر هو مؤشر الترابط الذي يمثله كائن مؤشر الترابط لفئة MyThread الجديدة.
تشير الخطوط من 21 إلى 23 إلى أنه يمكن إيقاف موضوع لم يتم البدء بعد. تأثيره هو: عندما يبدأ الخيط ، ينتهي على الفور.
التعليقات بعد السطر 48 تظهر بعمق لماذا تم إهمال طريقة STOP ()! لماذا هو غير آمن.
على سبيل المثال ، يحتوي مؤشر ترابط Threada على شاشات مسؤولة عن حماية بعض الموارد الحرجة ، مثل مقدار التحويلات المصرفية. عندما تكون عملية النقل قيد التقدم ، يقوم مؤشر الترابط الرئيسي باستدعاء threada.stop (). نتيجة لذلك ، يتم إصدار الشاشة ، والموارد التي تحميها (مقدار النقل) من المحتمل أن تكون غير متسقة. على سبيل المثال ، انخفض الحساب A بمقدار 100 ، في حين أن الحساب B لم يزيد بمقدار 100.
ثانياً ، آلية المقاطعة
هناك الكثير من التفاصيل حول كيفية استخدام آلية المقاطعة بشكل صحيح في Java. تعكس كل من الأساليب المقاطعة () و isInterredred () ما إذا كان الخيط الحالي في حالة متقطعة.
① متقطع ()
/*** اختبارات ما إذا كان الخيط الحالي قد انقطع. يتم مسح الحالة* <i> المقاطعة </i> من مؤشر الترابط بواسطة هذه الطريقة. وبعبارة أخرى ، إذا تم استدعاء هذه الطريقة مرتين على التوالي ، ستعود المكالمة الثانية* كاذبة (ما لم تتم مقاطعة الخيط الحالي مرة أخرى ، بعد أن تم مسح المكالمة الأولى من حالة المقاطعة* وقبل أن تقوم المكالمة الثانية بفحصها). مقاطع ؛* <code> false </code> خلاف ذلك.
من التعليقات الموجودة في الكود المصدري ، فإنه يختبر حالة المقاطعة للخيط الحالي ، وستقوم هذه الطريقة بمسح حالة المقاطعة.
②isinterredred ()
/*** اختبارات ما إذا كان هذا الموضوع قد توقف. لا تتأثر الحالة <i> المقطوعة* من مؤشر الترابط من هذا الطريقة. ISInterrupted () {return isInterrupted (false) ؛}كما يتضح من تعليقات التعليمات البرمجية المصدر ، لن تقوم طريقة ISInterrupted () بمسح حالة المقاطعة.
③difference بين طريقة المقاطعة () وطريقة انقطاع ()
كما يتضح من الكود المصدري ، تسمى كلتا الطريقتين IsInterredred (Boolean Clearnerpreated) ، باستثناء أن واحدة مع المعلمة صحيحة والآخر مع المعلمة خاطئة.
/*** اختبارات إذا تم مقاطعة بعض الخيط. تتم إعادة تعيين الحالة المقطوعة* على أساس قيمة الانقطاعات التي تم تمريرها*///خاص المناطق المنطقية المحلية (المنطقية المنطقية) ؛
لذلك ، فإن الفرق الأول هو أن المرء يمسح بتات العلم المقاطعة والآخر لا يزيل بتات العلم المقاطعة.
بعد تحليل الكود المصدري ، يمكنك رؤية الفرق الثاني في بيان الإرجاع:
مقاطعات منطقية ثابتة عامة () {return currentThread ()المقاطع () يختبر الحالة المقاطعة للخيط الحالي. يختبر ISInterrupted () مؤشر الترابط الذي يمثله الكائن الذي يستدعي الطريقة. إحداها طريقة ثابتة (يختبر حالة المقاطعة للخيط الحالي) ، والآخر هو طريقة مثيل (يختبر حالة المقاطعة للموضوع الذي يمثله كائن المثيل).
فيما يلي مثال محدد لتوضيح هذا الاختلاف.
هناك فئة خيط مخصصة على النحو التالي:
الطبقة العامة myThread يمتد Thread {Overridepublic void run () {super.run () ؛ for (int i = ؛ i <؛ i ++) {system.out.println ("i =" + (i +)) ؛}}}}}}دعونا أولاً نلقي نظرة على مثال طريقة المقاطعة ():
الفئة العامة تشغيل {public static void main (String [] args) {try {mythread thread = new myThread () ؛ thread.start () ؛ thread.sleep () ؛ thread.Interrupt () ؛ // thread.currentThRead (). interrupt () ؛ system.out.println ("stop؟ = // ...يبدأ السطر 5 مؤشر ترابط الخيط ، ويجعل السطر 6 نوم الخيط الرئيسي لمدة ثانية واحدة ، بحيث يكون لخيط مؤشر الترابط فرصة للحصول على تنفيذ وحدة المعالجة المركزية.
بعد أن ينام الخيط الرئيسي لمدة 1 ثانية ، يستأنف التنفيذ إلى السطر 7 ويطلب مقاطعة سلسلة الرسائل.
الخط 9 يختبر ما إذا كان الخيط في حالة متقطعة. أي موضوع يتم اختباره هنا؟ ؟ ؟ الجواب هو الموضوع الرئيسي. لأن:
(1) المقاطع () يختبر حالة المقاطعة للمعلومات الحالية
(2) ينفذ مؤشر الترابط الرئيسي عبارة السطر التاسع ، وبالتالي فإن الخيط الرئيسي هو الخيط الحالي
دعونا نلقي نظرة على مثال طريقة ISInterrupted ():
الفئة العامة تشغيل {public static void main (string [] args) {try {myThread thread = new MyThread () ؛ thread.start () ؛ thread.sleep () ؛ thread.interrupt () ؛ system.out.println ("هل تتوقف؟ ="على السطر 8 ، طريقة ISInterrupted () تسمى كائن مؤشر الترابط. لذلك ، يتم اختبار حالة المقاطعة للموضوع الذي يمثله كائن مؤشر الترابط. منذ أن كان على السطر 7 ، يطلب مؤشر الترابط الرئيسي مقاطعة مؤشر ترابط الخيط ، النتيجة على السطر 8 هي: TRUE