Java / دليل حلول تحريري
تشخيص السباقات والتعارضات وتسرب الخيوط
صنف أخطاء النتائج المشتركة ودورات الاعتماد وغياب تنظيف العمال بإعادة محدودة وأدلة تشغيل محمية.
قاعدة معرفة للقراءة فقط · بلا تعليقات عامة
تعرّف على الأعراض
قد ينتج السباق زيادات مفقودة أوحالة قديمة أوحقولاً غير متسقة دون استثناء، وتترك الدورة المهام تنتظر بلا نهاية.
قد يظهر التسرب بنمو الخيوط أو بقاء JVM بعد العمل. لا يثبت العدد وحده التسرب، وتحتاج خيوط21 الافتراضية تفسيراً واعياً بالإصدار.
افهم الأسباب المحتملة
- قد تغيب مزامنة موحدة أوينعكس ترتيب الموارد أوينتظر العامل عملاً في المنفذ المشبع نفسه.
- قد تتكرر المنفذات أو لا تغلق أوتبتلع المقاطعة أوتحتجز المهام مواردها. يخفي النوم السباق ولا يصلح التداخل المسموح.
صنف السلوك واحفظ الحمل
سجل الإصدار والتزامن والمنفذ والطابور وهوية المهمة وعرض الصحة أوالتأخر. افصل النتيجة الخاطئة والانتظار والدورة المثبتة. أعد ببيانات مصطنعة في عملية تملكها مع مهلة. لا تتصل بعمليات تطبيق مضبوطة ولا تنشر تفريغاً يحوي أسراراً.
فسّر التداخل غير الصالح
في count++ بيّن قراءة خيطين للقديم قبل كتابتهما. لا تجعل volatile العملية المركبة ذرية. استخدم مراقباً واحداً للثابت أوذرية مناسبة. ينفذ المثال تحديثاً محدوداً ويطبع بعد join؛ ولا تختلق خرجاً ثابتاً للنسخة المتسابقة.
public class Main {
public static void main(String[] args) throws Exception {
var count=new java.util.concurrent.atomic.AtomicInteger();
Thread worker=new Thread(()->{for(int i=0;i<100;i++) count.incrementAndGet();});
worker.start();worker.join();
System.out.println(count.get());
}
}
100
كل زيادة ذرية والقراءة بعد الانتهاء، ويحتاج ثابت عدة حقول تصميماً أوسع.
تتبع المالك والموارد المطلوبة
اجمع دليلاً مخولاً بأدوات الإصدار واتبع كل منتظر إلى مالك مورده حتى تثبت الدورة. لا يثبت خيط محجوب وحده شيئاً. ليست المراقبات المصدر الوحيد؛ قد يتجوع منفذ عامل واحد ينتظر مهمة فيه دون دورة مراقب. وحّد الترتيب أوأزل الاعتماد حسب الدليل.
أصلح ملكية العامل والإلغاء
حدد مالكاً وموعد إغلاق لكل منفذ. توقف shutdown القبول وتحاول shutdownNow المقاطعة لا قتل شيفرة آمنًا. انشر InterruptedException أوأعد العلامة عند تعذر النشر. قيّد الطابور والمهام كيلا يشبه الحمل تسرباً. يحتاج17 تنظيفاً صريحاً وتحتاج أمثلة AutoCloseable الأحدث تحقق إصدارها.
أثناء فحص التسرب، اكتب من يملك كل مجموعة عمال ومتى يفترض أن ينتهي عمرها. قد يكون مجمع صغير مستقر ينتظر عملاً لاحقاً سليماً تماماً، بينما يختلف عنه إنشاء مجمع جديد لكل طلب ثم تركه حياً. لا تعالج الحالتين بزيادة حد الخيوط أو الذاكرة. تحقق من أن انتهاء الطلب يحرر ما يملكه من عمال ومراجع إلى بياناته، وراجع أين يفترض أن ينفذ الإغلاق فعلاً. بهذه الطريقة يرتبط الاتجاه المرصود بقرار عمر له مسؤول واضح، بدلاً من تفسير أي رقم متزايد على أنه مشكلة في جامع القمامة أو في نظام التشغيل دون دليل على الجذر الحقيقي للاحتجاز.
فسّر اللقطات وأدلة الخيوط الافتراضية
قارن لقطات محدودة متكررة بحمل متكافئ لتمييز العمال الخاملين من تراكم المهام. تختلف تغطية JFR والتفريغ حسب الإصدار خاصة للافتراضية، فاتبع توثيقه واحم المكدس والمعاملات. حدد مالك احتجاز أو دورة أوثابتاً مكسوراً لا رقماً كبيراً على شاشة.
تحقق من نجاح الإصلاح
تحقق من التداخل المحدد باستخدام مزالج أو متعاونين مضبوطين بدلاً من الاعتماد على النوم، ثم نفذ حملاً متزامناً ممثلاً ومحدوداً بمهلة كلية. افحص الحالة النهائية الدقيقة وملاحظة إخفاق المهام وحدود الطابور وسياسة المقاطعة وانتهاء العمال بعد الإغلاق. لا تعتبر نجاح اختبار سباق مرات كثيرة إثباتاً لكل تنفيذ يسمح به نموذج ذاكرة Java؛ اربط الاختبار بتعليل بروتوكول الملكية والمزامنة. تحقق أيضاً من عدم تكرار أي أثر خارجي بعد إلغاء أو إعادة محاولة، ومن أن إصلاح النتيجة لم يترك عاملاً غير منته أو مورداً محتجزاً يجعل التطبيق يبدو صحيحاً أثناء العمل ثم يفشل في الخروج.
امنع تكرار المشكلة
- فضّل الرسائل الثابتة أوحصر الخيط إن بسّطا الملكية. وثق المزامنة والقبول والعمر والتشخيص المرتبط بالإصدار. اختبر حد الحادثة الحقيقي ولا تعتمد زيادة الحجم والمهلة بلا نهاية.