هل هناك أي طريقة في جافا لتسجيل * كل * مقاطعة الخيط؟

StackOverflow https://stackoverflow.com/questions/799023

سؤال

أود تسجيل الدخول بطريقة أو بأخرى في كل مرة Thread.interrupt() يسمى، وتسجيل الخيط الذي أصدر مكالمة (وتكدسه الحالي) بالإضافة إلى تحديد المعلومات التي تتم مقاطعة الموضوع.

هل هناك طريقة للقيام بذلك؟ البحث عن معلومات، رأيت شخصا ما يشير إلى إمكانية تنفيذ مدير الأمن. هل هذا شيء يمكن القيام به في وقت التشغيل (على سبيل المثال، في عميل التطبيق الصغير أو Web Start)، أو هل تحتاج إلى أداة JVM المثبتة للقيام بذلك؟

أو هل هناك طريقة أفضل للقيام بذلك؟

هل كانت مفيدة؟

المحلول

كخانت سريع، كان هذا كثيرا أسهل القيام به مما اعتقدت أنه سيكون. نظرا لأن هذا اختراق سريع، لم أفعل أشياء مثل التأكد من أن تتبع المكدس عميق بما يكفي قبل تغيير الصفيف، إلخ. قمت بإدراج ما يلي في منشئ التطبيق الصغير الموقعي الخاص بي:

log.info("Old security manager = " + System.getSecurityManager());
System.setSecurityManager(new SecurityManager() {
      @Override
      public void checkAccess(final Thread t) {
        StackTraceElement[] list = Thread.currentThread().getStackTrace();
        StackTraceElement element = list[3];
        if (element.getMethodName().equals("interrupt")) {
          log.info("CheckAccess to interrupt(Thread = " + t.getName() + ") - "
                   + element.getMethodName());
          dumpThreadStack(Thread.currentThread());
        }
        super.checkAccess(t);
      }
    });

و ال dumpThreadStack الطريقة كما يلي:

public static void dumpThreadStack(final Thread thread) {
  StringBuilder builder = new StringBuilder('\n');
  try {
    for (StackTraceElement element : thread.getStackTrace()) {
      builder.append(element.toString()).append('\n');
    }
  } catch (SecurityException e) { /* ignore */ }
  log.info(builder.toString());
}

لا أستطيع أبدا، بطبيعة الحال، اترك هذا في رمز الإنتاج، لكنه كهنى أن أخبرني بالضبط ما الذي يسببه interrupt() أنني لم أتوقع. وهذا هو، مع هذا الرمز في المكان، أحصل على تفريغ مكدس لكل مكالمة Thread.interrupt().

نصائح أخرى

قبل تجربة أي شيء برية للغاية، هل فكرت في استخدام تصحيح جافا api.ب أعتقد أن الاستيلاء على مفاتيح المناهجين على الخيط. ماذا تفعل ذلك.

Eeeek، هذه هي الواجهة القديمة، يجب عليك أيضا التحقق من Oout الجديد أداة JVM واجهه المستخدم.

أود أن أنظر إلى جيوب وقدراتها لالتفاف مكالمات الطريقة. أ تنفيذ تنفيذ حول ال interrupt() يجب أن تساعد الطريقة هنا.

لاحظ أنه نظرا لأنك تتطلع إلى اعتراض مكالمة طريقة نظام Java (بدلا من كود التطبيق الخاص بك)، وما سبق مايو لا تكون مناسبة. هذا الموضوع يبدو أن اقترح أنه ممكن، ولكن لاحظ أنه خلق منسوجة rt.jar.

كما قال آخرون ... إذا كان شيء لمرة واحدة JVMTI هو ربما الطريقة المتشددين للذهاب. ومع ذلك، مثل المرح يمكن أن تستخدم مكتبة ASM واجهات برمجة تطبيقات الأجهزة لإنشاء وكيل يدرج مكالمة إلى طريقة ثابتة قمت بإنشائها قبل الخيط. ) طريقة لفعل الشيء نفسه، أعتقد أنه يمكنك القيام بذلك).

يستغرق كلاهما بعض الوقت للتعلم ولكنه ممتع للغاية للعمل معه وبمجرد الحصول على تعليق يمكنك استخدامها لجميع أنواع الأشياء المضحكة في المستقبل :-) ليس لدي أي مقتطفات جيدة حقا للصقها هنا في الوقت الحالي ولكن إذا كنت جوجل حول ASM وربما ننظر إلى JIP لبعض الاستخدام الإبداعي ASM، أعتقد أنك ستجد إلهاما.

جيب: java profiler التفاعلية

يمكنك محاولة أيضا مع JMX:

ManagementFactory.getThreadMXBean().getThreadInfo(aThreadID)

مع ال Threadinfo. كائن يمكنك تسجيل:

  • كومة أثر الموضوع
  • معلومات مساعدة المستخدم مثل الاسم والحالة وما إلى ذلك
  • إلخ

تعديل

استخدم GetallhreadIds () من أجل الحصول على قائمة معرفات المؤلم المباشر:

long[] ids = ManagementFactory.getThreadMXBean().getAllThreadIds();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top