سؤال

كيف يمكنني برمجيا اكتشاف أن حالة توقف تام قد حدث في برنامج Java؟

لا يوجد حل صحيح

نصائح أخرى

يمكنك القيام بهذا برمجيا باستخدام ThreadMXBean تلك السفن مع JDK:

ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long[] threadIds = bean.findDeadlockedThreads(); // Returns null if no threads are deadlocked.

if (threadIds != null) {
    ThreadInfo[] infos = bean.getThreadInfo(threadIds);

    for (ThreadInfo info : infos) {
        StackTraceElement[] stack = info.getStackTrace();
        // Log or store stack trace information.
    }
}

من الواضح أنك يجب أن تحاول عزل أي خيط يقوم بإجراء فحص هذا الجمود - خلاف ذلك إذا كان هذا الجمود الجمود لن يكون قادرا على تشغيل الشيك!

بالمناسبة، هذا ما يستخدمه JConsole تحت الأغطية.

تلميح مفيد واحد للتحقيق:

إذا كنت تستطيع التقاط التطبيق الأحمر، واشتبه في حالة توقف تام، ثم اذهب واضغط على "كسر CTRL-BREAT" في نافذة وحدة التحكم Java.exe (أو "Ctrl- " على Solaris / Linux). سوف تفريغ JVM الوضع الحالي وتتبع المكدس لجميع المواضيع، ومعرفة الأقفال الميتة وصفها بدقة.

سيبدو شيئا من هذا القبيل:

Full thread dump Java HotSpot(TM) Client VM (1.5.0_09-b03 mixed mode):

"[Test Timer] Request Queue" prio=6 tid=0x13d708d0 nid=0x1ec in Object.
    wait() [0x1b00f000..0x1b00fb68]
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Unknown Source)
    at library.util.AsyncQueue.run(AsyncQueue.java:138)
        - locked <0x02e70000> (a test.server.scheduler.SchedulerRequestQueue)

    ...

Found one Java-level deadlock:
=============================
"Corba service":
  waiting to lock monitor 0x13c06684 (object 0x04697d90, a java.lang.Object),
  which is held by "[Server Connection] Heartbeat Timer"
"[Server Connection] Heartbeat Timer":
  waiting to lock monitor 0x13c065c4 (object 0x0467e728, a test.proxy.ServerProxy), which is held by "Corba service"

Java stack information for the threads listed above:
===================================================
"Corba service":
    at test.proxy.ServerProxy.stopHBWatchDog(ServerProxy:695)
    - waiting to lock <0x04697d90> (a java.lang.Object)
    ...

يمكنك الكشف عن المواضيع الجميلة المسدودة برمجيا باستخدام ThreadMxbean Class.here هو التعليمات البرمجية،

    ThreadMXBean bean = ManagementFactory.getThreadMXBean();

    long ids[] = bean.findMonitorDeadlockedThreads();

    if(ids != null)
    {
        ThreadInfo threadInfo[] = bean.getThreadInfo(ids);

        for (ThreadInfo threadInfo1 : threadInfo)
        {
            System.out.println(threadInfo1.getThreadId());    //Prints the ID of deadlocked thread

            System.out.println(threadInfo1.getThreadName());  //Prints the name of deadlocked thread

            System.out.println(threadInfo1.getLockName());    //Prints the string representation of an object for which thread has entered into deadlock.

            System.out.println(threadInfo1.getLockOwnerId());  //Prints the ID of thread which currently owns the object lock

            System.out.println(threadInfo1.getLockOwnerName());  //Prints name of the thread which currently owns the object lock.
        }
    }
    else
    {
        System.out.println("No Deadlocked Threads");
    }

انقر هنا لمزيد من المعلومات حول كيفية اكتشاف المواضيع الجماعية.

الجرارم هي مكتبة للكشف عن طريق الجمود والتجنب. ويشمل دعم ل:Thread.join, CyclicBarrier, CountDownLatch, Phaser, ، وReentrantLock.

لاستخدام الأرجال تحتاج إلى أداة التعليمات البرمجية الخاصة بك. إما من خلال واحدة من فئاتها الصبطة أو تلقائيا مع البرموسية Instrumarar jarmusc.

java -jar jarmusc.jar yourprogram.jar checkedprogram.jar

المدخل yourprogram.jar هو البرنامج الذي تريد التحقق منه. الناتج هو نفس البرنامج مع الشيكات لإيجاد أي طريق مسدود تلقائيا.

الحواجز تحتاج إلى بعض المساعدة

التحقق من الجمود مع الفصول CyclicBarrier, CountDownLatch, Phaser أمر صعب بعض الشيء --- على سبيل المثال، لا يمكن ل JConsole اكتشاف هذه الأنواع من الجمود الجمود. يحتاج الجرارم إلى القليل من المساعدة منك: يجب عليك تحديد مؤشرات الترابط تؤثر على التزامن، ونحن نسمي هذه مسجل الخيوط.

في أقرب وقت ممكن، يجب أن يمثل الموضوع نفسه كما هو مسجل. مكان جيد لتمييز المواضيع المسجلة في طريقة البداية Runnable.run. JArmus.register(latch);

مثال

البرنامج التالي الذي تم تحديده بشكل صحيح بواسطة jarmus:

final CountDownLatch latch = new CountDownLatch(2);
final CyclicBarrier barrier = new CyclicBarrier(2);
final Queue<Exception> exceptions = new ArrayDeque<>();
Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            JArmus.register(barrier); // do not forget to register!
            JArmus.register(latch); // do not forget to register!
            latch.countDown();
            latch.await();
            barrier.await();
        } catch (Exception e) {
            exceptions.add(e);
        }
    }
});
Thread t2 = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            JArmus.register(barrier); // do not forget to register!
            JArmus.register(latch); // do not forget to register!
            barrier.await();
            latch.countDown();
            latch.await();
        } catch (Exception e) {
            exceptions.add(e);
        }
    }
});
t1.start();
t2.start();

قد ترغب في النظر IBM's Mtrat.. وبعد الوقاية أفضل من العلاج بعد كل شيء. ال مجموعة تطوير البرمجيات متعددة يأتي أيضا مع أداة كشف الجمود.

إذا كنت لا تحتاج إلى اكتشاف برنامجي يمكنك القيام بذلك عبر jconsole.; ؛ في علامة التبويب مؤشر الترابط، يوجد زر "كشف حالة توقف تام". في JDK6 هذا القفل الكشف لكل من الشاشات الجوهرية و j.u.c Lockس

ارفع JConsole عبر $JAVA_HOM/bin/jconsole أمر

هناك رمز هنا: http://www.java2s.com/code/java/development-class/performingdeadlockdectionprogramplicnwithintheapplicationusthejavalangmanagementapi.htm.

السحر يحدث في ThreadMonitor.findDeadlock():

  public boolean findDeadlock() {
    long[] tids;
    if (findDeadlocksMethodName.equals("findDeadlockedThreads")
        && tmbean.isSynchronizerUsageSupported()) {
      tids = tmbean.findDeadlockedThreads();
      if (tids == null) {
        return false;
      }

      System.out.println("Deadlock found :-");
      ThreadInfo[] infos = tmbean.getThreadInfo(tids, true, true);
      for (ThreadInfo ti : infos) {
        printThreadInfo(ti);
        printLockInfo(ti.getLockedSynchronizers());
        System.out.println();
      }
    } else {
      tids = tmbean.findMonitorDeadlockedThreads();
      if (tids == null) {
        return false;
      }
      ThreadInfo[] infos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE);
      for (ThreadInfo ti : infos) {
        // print thread information
        printThreadInfo(ti);
      }
    }

    return true;
  }

هذا يدعو واجهة برمجة تطبيقات ThreadMXBean الذي يحتوي على اسم مختلف في Java 5 و 6 (وبالتالي الخارجي if()).

يتيح مثال التعليمات البرمجية أيضا مقاطعة الأقفال، بحيث يمكنك حتى كسر الجمود.

Tempus-Fugit. تنفذه أيضا مع فئة إلقاء الخيط البرنامجي البرنامجي. يتم تنفيذها باستخدام آلية MBEAN المذكورة أعلاه وتقدم انخفاضا في حل المخادع السوبر خارج الصندوق.

في حال كنت تريد القيام به في وقت التشغيل، يمكنك استخدامها مراقبة من أجل هذا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top