توفر آلية مقاطعة مؤشر الترابط طريقة لتستيقظ مؤشر ترابط من الانتظار الحظر ، في محاولة لمقاطعة تدفق المعالجة الحالي للمعالجة والاستجابة لأوامر جديدة. تترك جافا هذه الحرية للمطورين ، ويجب أن نستفيد منها بشكل جيد.
اليوم سوف نتحدث عن آلية المقاطعة لخيوط جافا.
توفر آلية مقاطعة الخيط طريقة لها استخدامان شائعان:
استيقظ الخيط من منع الانتظار وجعل معالجة "المقاطعة التي يتم التحكم فيها" المقابلة.
حاول إبلاغ موضوع الهدف: يرجى مقاطعة تدفق المعالجة الحالي والرد على أوامر جديدة.
خذ الغرض الأول كمثال ، يرجى الاطلاع على الرمز التالي:
Synchronized (lock) {try {when (! check ()) {lock.wait (1000) ؛ }} catch (interruptedException e) {E.PrintStackTrace () ؛ }}يستخدم هذا الرمز آلية الانتظار/الإخطار التي توفرها Java. سيتم تنفيذ مؤشر ترابط Lock.Wait (). هناك ثلاث حالات لاستعادة الخيط لتشغيله.
1. تنتهي المهلة 1000ms ، ويتم تنفيذ الكود التالي بشكل طبيعي.
2. يقوم مؤشر ترابط آخر بتنفيذ الكود التالي للاستيقاظ بنشاط
Synchronized (lock) {lock.notifyall () ؛ // أو lock.notify () ؛}سيؤدي هذا أيضًا إلى تنفيذ الكود التالي بشكل طبيعي.
3. موضوع آخر مطلوب للانتظار هو "مقاطعة"
// احصل على الإشارة إلى مؤشر ترابط الانتظار A ؛ A.Interrupt () ؛
الخيط A الذي يتم "مقاطعة" سوف يرمي استثناء المقاطع في lock.wait ().
خلاصة القول ، يمكنك التفكير في object.wait () تقوم بهذه الأشياء داخليًا:
boolean checkTimeOut = timeout> 0 ؛ thread current = thread.currentThRead () ؛ lock.addwaiter (current) ؛ بينما (! current.isnotified ()) {if (current.isinterrupted ()) {current.clearterrupted () ؛ رمي جديد interruptedException () ؛ } if (checkTimeOut) {if (timeout == 0) break ؛ نفذ الوقت--؛ }}هذا ليس دقيقًا تمامًا ، لأن الانتظار لا يستخدم طريقة "الاقتراع المزدحمة" للتحقق ، ولكن منطق الحكم على بتات العلم صحيح.
لنبدأ بعملية "الإصدار يدويًا المقاطعة" المذكورة أعلاه
// sun.nio.ch.InterreTruptiblepublic interruptible {void interrupt (thread var1) ؛} // java.lang.Threadprivate forructible interruptible interruptible ؛ private final object blockerlock = new object () ؛ public void interrupt () {if (this! متزامن (blockerlock) {interruptible b = Blocker ؛ if (b! = null) {interrupt0 () ؛ B.Interrupt (هذا) ؛ يعود؛ }} interrupt0 () ؛} // فقط لتعيين interrupt0 () ؛يمكن ملاحظة أن Thread.Interrupt () أول أذونات الحكام ، ثم يستدعي فعليًا Interrupt0 () لتعيين علامة مقاطعة مؤشر الترابط. إذا كان مؤشر الترابط الحالي يحتوي على مقاطعة NIO ، فسيقوم أيضًا باستدعاء.
لاحظ أن Interrupt0 () فقط يعين علامة مقاطعة مؤشر الترابط.
ماذا يحدث عندما لا يكون مؤشر الترابط حظرًا وليس في المناطق التي لا يتم التحكم فيها بواسطة منطق برنامج Java ، مثل object.wait () ، thread.join () ، thread.sleep ()؟ الجواب هو أنه لن يحدث شيء ، وما إذا كان الخيط قد توقف لا يمكن معرفته إلا عن طريق التحقق بنشاط من علامة المقاطعة.
كيف تتحقق؟ يعرض الموضوع واجهتين ، Thread.Interreded () و Thread.isinterrupted ().
// java.lang.Threadpublic static boolean interrupt () {return currentThread (). isInterrupted (true) ؛} isinterrupted () {return isInterrupted (false) ؛} iSinterredredredredredredredredredredredredredredredredredredredredredreded () ؛يمكن ملاحظة أن كلاهما يعتمدان على الانقطاع الداخلي (المنطقي) ، والذي سيعود ما إذا كان الخيط قد توقف ومسح علامة المقاطعة حسب الحاجة.
عندما يتم كتل استدعاء الوظائف ، فإن علامات دالة مكتبة Java ترميات المقاطعات في توقيع مصدر الحظر وتتطلب كتابة Try Catch للتعامل مع المقاطعات.
عندما يحجب مؤشر الترابط ، كما هو مذكور أعلاه ، يتحقق Java من علامة المقاطعة ، ومسحه أولاً ، ثم يلقي مقاطعًا.
// java.lang.Objectpublic Final Void Wait () رميات InterruptedException {wait (0) ؛} رميات الفراغ النهائي العام النهائي (فترة طويلة).إذا تلقى مؤشر ترابط مقاطعًا ، ثم يقوم بتنفيذ الكود الذي سيلقي حظرًا ، فسوف يستمر في حظر "بغض النظر". لأن Java يمسح العلم المقاطعة داخليًا!
غالبًا ما نكتب الأنواع الثلاثة التالية من التعليمات البرمجية التي تتعامل مع InterruptedException:
تعامل مع المقاطعات إلى الطبقة العليا للمعالجة.
public void foo () remrows interruptedException {synchronized (lock) {lock.wait () ؛ }}InterruptedException إعادة تعيين بتات العلم المقاطعة.
حاول {synchronized (lock) {lock.wait () ؛ }} catch (interruptedException e) {thread.currentThread (). interrupt () ؛ //استراحة؛ }أنهي عملك أولاً ، ثم رمي مقاطعًا مرة أخرى.
شريط باطل عام () يلقي interruptedException {interruptedException ie = null ؛ Boolean Do = false ؛ بينما (! تم) {synchronized (lock) {try {lock.wait () ؛ } catch (interruptedException e) {ie = e ؛ يكمل؛ }} تم = صحيح ؛ } if (ie! = null) {throw ie ؛ }}إذا تجاهل مؤشر ترابط العلم المقاطعة ومقاطعته ، فإنه لا يزال يعمل بشكل جيد. ولكن هذا يتعارض مع نيتنا الأصلية في تصميم MultiThreading. نريد أن تتعاون المواضيع بشكل متناغم وبطريقة منظمة لتحقيق وظائف محددة ، لذلك يجب أن تستجيب مؤشرات الترابط التي يتم التحكم فيها للمقاطعات. ويجب أن نستفيد بشكل جيد من هذه الحرية التي تركتها جافا للمطورين.
ما سبق هو كل المعرفة ذات الصلة بآلية مقاطعة Java المقاطعة التي قدمتها لك هذه المرة. إذا كنت لا تفهم أي شيء ، فيمكنك مناقشته في منطقة الرسالة أدناه. شكرا لدعمكم ل wulin.com.