كيف يمكنني مقاطعة بيان متزامن في جافا؟
-
21-09-2019 - |
سؤال
لدي خيطان يرغبان في التزامن على نفس الكائن. ثيد A
يجب أن تكون قادرًا على مقاطعة الخيط B
إذا كان هناك حالة معينة قد تم تملأها. فيما يلي بعض الرمز الزائفة لما يفعله الخيط/يجب أن يفعله.
أ:
public void run()
{
while(true)
{
//Do stuff
synchronized(shared)
{
//Do more stuff
if(condition)
{
B.interrupt();
}
}
}
}
ب:
public void run()
{
while(true)
{
try
{
//Do stuff
synchronized(shared)
{
//Do more stuff
}
}
catch(InterruptedException e)
{
continue;
}
}
}
هذا هو الموقف الذي لا يمكنني حله:
- خيط
A
يمسك المورد المشترك ويقوم ببعض الأشياء. - وفي الوقت نفسه ، الموضوع
B
يصل إلى الكتلة المتزامنة ، وينتظرA
لإصدار موردها المشترك. - خيط
A
, أثناء القيام بالأشياء ، أدرك أن الموضوع B لا ينبغي أن يكون لديه المورد المشترك ، ويحاول مقاطعة الخيطB
. لكن الموضوعB
لقد تجاوز بالفعل النقاط التيInterruptedException
يمكن إلقاؤه.
سؤالي هو ، هل هناك أي طريقة لمقاطعة خيط أثناء انتظار أن يكون synchronized
على شيء ما؟
المحلول
لهذا النوع من الأشياء ، يجب عليك استخدام الفصول في java.util.concurrent.locks
- لديهم قدرات أكبر بكثير ، بما في ذلك الأقفال القابلة للمقاطعة.
تعديل: إذا لم تتمكن wait()
/notify()
الميكانيكية ، ولكن من السهل تقديم حشرات خفية.
نصائح أخرى
في الواقع يجب عليك استخدام الأقفال أو تنفيذ الأشياء الخاصة بك مع Object.wait()
, Object.notify()
و Object.notifyAll()
الأساليب (يتم تنفيذ الأقفال بالفعل معهم). لا تنسَ التعامل مع ما يسمى بـ "الاستيقاظ الزائف" (wait()
قد يعود حتى لو لم يتم الاتصال notify()
أو notifyAll()
, ، لذلك يجب أن يتم استدعاؤه دائمًا في حلقة تتحقق من أن الحالة التي تنتظرها راضية).
لا ولكن reentrantlock.lockly ()
يتصرف بشكل مشابه للبدائية monitorenter
تعليمات ويمكن مقاطعة.