مستوى المعرفة المطلوب لفهم المقالة: لقد أكملت مهام Java Syntax وJava Core، وأنت الآن بصدد تعلم Java Multithreading. الجمود أو الجمود في Java أو الجمود هو خطأ يحدث عندما يكون للخيوط تبعية دورية على زوج من الكائنات المتزامنة. تخيل أن أحد الخيوط يدخل في شاشة الكائن
في هذه الحالة، يتم حظر كلا الخيطين وينتظر كل منهما الآخر لتحرير القفل. لكن لن يقوم أي منهم بذلك، لأنه للقيام بذلك يحتاجون إلى إكمال طريقتهم، ويتم حظرها بواسطة مؤشر ترابط آخر. لذلك كانوا عالقين حيث حدث ذلك
x
، والآخر يدخل في شاشة الكائن y
. إذا حاول مؤشر ترابط في كائن x
استدعاء أي طريقة متزامنة على الكائن y
، وحاول الكائن y
في نفس الوقت استدعاء أي طريقة متزامنة على الكائن x
، فسوف تتعثر مؤشرات الترابط في الانتظار. يوجد أدناه مثال من البرنامج التعليمي لمستندات Java حول مفهوم مثل الجمود. أين يحدث حظر الخيط هنا؟
public class Deadlock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s" + " has bowed to me!%n", this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s"
+ " has bowed back to me!%n",
this.name, bower.getName());
}
}
public static void main(String[] args) {
final Friend alphonse =
new Friend("Alphonse");
final Friend gaston =
new Friend("Gaston");
new Thread(new Runnable() {
@Override
public void run() {
// System.out.println("Thread 1");
alphonse.bow(gaston);
// System.out.println("Th: gaston bowed to alphonse");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
// System.out.println("Thread 2");
gaston.bow(alphonse);
// System.out.println("2.gaston waiting alph bowed");
}
}).start();
}
}
هناك أمران مهمان يجب فهمهما هنا:
- ما الذي يفعله بالضبط كل من سلاسل الرسائل التي تعمل بشكل متزامن؟
- ما الأقفال المستخدمة؟
Friend
: alphonse
و gaston
. كل واحد منهم لديه قفل خاص به. وبالتالي، هناك نوعان من هذه الأقفال: جيجولوس وجاستون. عند إدخال طريقة متزامنة لكائن ما، يتم قفل قفله، وعند الخروج من الطريقة، يتم تحريره (أو إلغاء قفله). الآن عن المواضيع. دعنا نسمي الخيط الأول Alphonse
(بحرف كبير لتمييزه عن الكائن ألفونس). وإليك ما يفعله (دعنا نسميه A
، اختصارًا لـ Alphonse
):
A: alphonse.bow(gaston) — получает лок alphonse;
A: gaston.bowBack(alphonse) — получает лок gaston;
A: возвращается из обоих методов, тем самым освобождая лок.
وهذا ما يفعله الموضوع في هذا الوقت Gaston
:
G: gaston.bow(alphonse) — получает лок gaston;
G: alphonse.bowBack(gaston) — получает лок alphonse;
G: возвращается из обоих методов, тем самым освобождая лок.
الآن دعونا نجمع هذه البيانات معًا ونحصل على الإجابة. يمكن أن تتشابك الخيوط (أي أن أحداثها ستحدث) بترتيب مختلف. سيعمل الجمود، على سبيل المثال، إذا كان الترتيب كما يلي:
A: alphonse.bow(gaston) — получает лок alphonse
G: gaston.bow(alphonse) — получает лок gaston
G: пытается вызвать alphonse.bowBack(gaston), но блокируется, ожидая лока alphonse
A: пытается вызвать gaston.bowBack(alphonse), но блокируется, ожидая лока gaston
deadlock
. ومع ذلك، من الممكن أيضًا نسج آخر، حيث سيكون لدى أحد الخيوط الوقت الكافي لإكماله قبل أن يبدأ الثاني:
A: alphonse.bow(gaston) — получает лок alphonse
A: gaston.bowBack(alphonse) — получает лок gaston
A: возвращается из обоих методов, открывая оба лока
G: gaston.bow(alphonse) — получает лок gaston
G: alphonse.bowBack(gaston) — получает лок alphonse
G: возвращается из обоих методов, открывая оба лока
في هذه الحالة، لا يوجد حظر متبادل للخيوط. على سبيل المثال، تمت إضافة بعض الطرق التي تسمح لمؤشر ترابط آخر بالحصول على الوقت للتنفيذ. عندما تعتمد النتيجة على ترتيب الأحداث التي تحدث في وقت واحد (الترتيب المخطط أو سرعة التنفيذ)، تسمى هذه العملية باللغة الروسية حالة السباق - "حالة السباق". ليس من المحتمل أن تتسبب جميع ظروف السباق في حدوث طريق مسدود، ومع ذلك، من خلال تجربتي، فإن ظروف السباق فقط هي التي تسبب الجمود. الإجابة بواسطة: ديف ليليثون
ماذا تقرأ: |
---|
مجموعة مطوري جافا: |
GO TO FULL VERSION