代码之家  ›  专栏  ›  技术社区  ›  Eddie

Java中有没有办法记录*每个*线程中断?

  •  6
  • Eddie  · 技术社区  · 15 年前

    我想每次都记日志 Thread.interrupt() 调用,记录发出调用的线程(及其当前堆栈)以及有关哪个线程被中断的标识信息。

    有办法做到这一点吗?在搜索信息时,我看到有人提到了实现安全管理器的可能性。这是可以在运行时完成的(例如,在Applet或Web启动客户端中),还是需要为已安装的JVM提供工具来完成?

    还是有更好的方法?

    5 回复  |  直到 15 年前
        1
  •  10
  •   Eddie    15 年前

    作为一个快速黑客,这是一个 大量 比我想象的要容易。由于这是一个快速的攻击,我没有在取消引用数组之前确保堆栈跟踪足够深,等等。我在签名小程序的构造函数中插入了以下内容:

    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() .

        2
  •  4
  •   Charlie Martin    15 年前

    在尝试任何过于疯狂的东西之前,您是否考虑过使用 Java debugging API

    JVM Tool Interface .

        3
  •  2
  •   Brian Agnew    15 年前

    AspectJ 以及它包装方法调用的功能。一 execution pointcut 周围 interrupt() 方法应该在这里有所帮助。

    也许 不合适。 This thread 似乎暗示这是可能的,但请注意,他创造了一个 rt.jar。

        4
  •  1
  •   Fredrik    15 年前

    正如其他人所说。。。如果是一次性的,JVMTI可能是最核心的方式。但是,使用asm库和instrumentation API创建一个代理,在Thread.interrupt()调用之前插入对您创建的静态方法的调用(或者更改Thread.interrupt()方法来执行相同的操作,我认为您可以这样做)。

    我现在真的没有什么好的片段可以粘贴在这里,但是如果你搜索ASM,或者看看JIP中ASM的一些创造性使用,我想你会找到灵感。

    联合执行计划: Java Interactive Profiler

        5
  •  0
  •   dfa    15 年前

    您也可以尝试使用JMX:

    ManagementFactory.getThreadMXBean().getThreadInfo(aThreadID)
    

    ThreadInfo

    • 一般用户信息,如姓名、状态等

    编辑

    long[] ids = ManagementFactory.getThreadMXBean().getAllThreadIds();