Pregunta

¿Cómo puedo programación detectar que un callejón sin salida se ha producido en un programa Java?

No hay solución correcta

Otros consejos

Usted puede hacer esto mediante programación utilizando el ThreadMXBean que se incluye con el 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.
    }
}

Obviamente, usted debe tratar de aislar lo que va a realizar este hilo cheque estancamiento - De lo contrario, si ese hilo interbloqueos que no será capaz de ejecutar la verificación

A propósito esto es lo que JConsole es el uso bajo las sábanas.

Un consejo útil para la investigación:

Si se puede tomar la aplicación manos en la masa y la sospecha se ha producido un estancamiento, ir y pulse la tecla "Ctrl-Break" en la ventana de la consola java.exe (o "Ctrl \" en Solaris / Linux). La JVM se volcará el estado actual y seguimiento de la pila de todas las discusiones, averiguar las cerraduras y precisa describirlos.

Se verá algo como esto:

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

Puede detectar los hilos de punto muerto utilizando programación ThreadMXBean class.Here es el código,

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

Haga clic aquí para obtener más información sobre cómo detectar los hilos de punto muerto.

JArmus es una biblioteca para detección de estancamiento y de evitación. Incluye soporte para: Thread.join, CyclicBarrier, CountDownLatch, Phaser, y ReentrantLock.

Para usar JArmus que necesita para instrumentar el código. Ya sea a través de uno de sus clases instrumentados o automáticamente con el jarmusc instrumentar JArmus.

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

El yourprogram.jar de entrada es el programa que desea comprobar. La salida es el mismo programa con cheques para encontrar automáticamente cualquier punto muerto.

Barreras necesitan un poco de ayuda

Verificación de los puntos muertos con las clases CyclicBarrier, CountDownLatch, Phaser es un poco complicado --- por ejemplo, JConsole no puede detectar este tipo de bloqueos. JArmus necesita un poco de ayuda de usted: debe especificar qué temas están influyendo en la sincronización, llamamos a estos hilos.

En cuanto sea posible, el hilo debe marcar como registrado. Un buen lugar para marcar hilos registrados está en el método de Runnable.run principio. JArmus.register(latch);

Ejemplo

El siguiente programa que bloquea al principio se identifica correctamente 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();

Es posible que desee considerar de IBM MTRAT . La prevención es mejor que curar después de todo. El kit Multicore de desarrollo de software también viene con una herramienta de detección de punto muerto.

Si no se requiere la detección programática puede hacerlo a través de la JConsole ; en la pestaña de rosca hay un botón de "detección de punto muerto". En JDK6 esta detectar cerraduras para ambos monitores intrínsecas y j.u.cs Lock

Ejecutar hasta el JConsole a través del comando $JAVA_HOM/bin/jconsole

No es aquí el código: http://www.java2s.com /Code/Java/Development-Class/PerformingdeadlockdetectionprogrammaticallywithintheapplicationusingthejavalangmanagementAPI.htm

La magia sucede en 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;
  }

Este llama a un API de la ThreadMXBean que tiene un nombre diferente en Java 5 y 6 (de ahí el if() exterior).

El ejemplo de código también permite interrumpir las cerraduras, lo que incluso puede romper el punto muerto.

tempus-fugit también implementa junto con una clase de dumping hilo programática. Se implementa utilizando el mecanismo de mbean mencionado anteriormente y ofrece una caída en, fuera de la caja de solución de Super Duper.

En caso de que quiera que se haga en tiempo de ejecución puede utilizar de vigilancia para que.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top