Pregunta

Me gustaría de alguna manera cada vez que ingrese Thread.interrupt() se llama, el registro de qué hilo emitió la llamada (y su pila actual), así como información de identificación sobre el que se está interrumpido hilo.

¿Hay una manera de hacer esto? La búsqueda de información, vi a alguien hacer referencia a la posibilidad de implementar un controlador de seguridad. ¿Esto es algo que se puede hacer en tiempo de ejecución (por ejemplo, en un applet o cliente Web Start), o necesita a la herramienta de la JVM instalado para hacer esto?

O hay una mejor manera de hacer esto?

¿Fue útil?

Solución

Como un corte rápido, éste fue un mucho más fácil de hacer de lo que pensaba que sería. Dado que este es un corte rápido, no lo hice cosas como asegurarse de que el seguimiento de la pila es lo suficientemente profunda antes de eliminación de referencias a la matriz, etc. insertar el siguiente en mi constructor del applet firmado:

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);
      }
    });

y el método dumpThreadStack es como sigue:

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());
}

Nunca podría, por supuesto, dejar esto en el código de producción, pero fue suficiente para decirme exactamente por cuál de ellos estaba causando un interrupt() que no esperaba. Es decir, con este código en su lugar, aparece un volcado de pila para cada llamada a Thread.interrupt().

Otros consejos

Antes de intentar cualquier cosa demasiado salvaje, ¿ha considerado el uso de la de Java depurar API? Me parece que captura MethodEntryEvents en Thread.interrupt () lo harían.

Eeek, que es la interfaz de edad, usted debe también comprobar oout la nueva href="http://java.sun.com/j2se/1.5.0/docs/guide/jpda/enhancements.html" rel="nofollow noreferrer"> Interfaz .

Me gustaría ver AspectJ y sus capacidades para envolver las llamadas a métodos. Un ejecución pointcut alrededor el método interrupt() debe ayudar aquí.

Tenga en cuenta que, dado que usted está buscando para interceptar un método llamado sistema de Java (en comparación con el código de aplicación), por encima de la pueden no ser adecuado. Este hilo parece sugerir que es posible, pero tenga en cuenta que él es creado un tejida rt.jar.

Como otros han dicho ... Si se trata de una cosa de una sola vez JVMTI es probablemente la forma más graves que ir. Sin embargo, igual de divertido que podría ser utilizar la biblioteca ASM y las API de instrumentación para crear un agente que se inserta una llamada a un método estático que ha creado justo antes de la llamada Thread.interrupt () (o tal vez altera la Thread.interrupt ( ) método para hacer lo mismo, creo que se puede hacer eso).

Tanto toma algún tiempo para aprender, pero es muy divertido trabajar con él y una vez que la bodega de la misma se puede utilizar para todo tipo de cosas raras en el futuro :-) Realmente no tengo ninguna buena fragmentos para pegar aquí en este momento, pero si google en torno ASM y tal vez miro la JIP para algún uso creativo de la ASM Creo que va a encontrar la inspiración.

JIP: interactivo de Java Profiler

Usted podría tratar también con JMX:

ManagementFactory.getThreadMXBean().getThreadInfo(aThreadID)

con el ThreadInfo objeto puede iniciar sesión:

  • el seguimiento de la pila de la rosca
  • información general Userful como nombre, estado, etc.
  • etc.

Editar

getAllThreadIds uso () con el fin de obtener la lista de identificadores de hilo en vivo:

long[] ids = ManagementFactory.getThreadMXBean().getAllThreadIds();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top