2010-01-06 23 views
8

El programa siguiente muestra el problema (la última JVM & otras cosas):Thread.isInterrupted no funciona, Thread.interrupted hace

public static void main(String[] args) throws InterruptedException { 
    // if this is true, both interrupted and isInterrupted work 
    final boolean withPrint = false; 

    // decide whether to use isInterrupted or interrupted. 
    // if this is true, the program never terminates. 
    final boolean useIsInterrupted = true; 

    ExecutorService executor = Executors.newSingleThreadExecutor(); 
    final CountDownLatch latch = new CountDownLatch(1); 
    Callable<Void> callable = new Callable<Void>() { 
     @Override 
     public Void call() throws Exception { 
      Random random = new Random(); 
      while (true) { 
       if (withPrint) { 
        System.out.println(random.nextInt()); 
        System.out.flush(); 
       } 
       if (useIsInterrupted) 
       { 
        if (Thread.currentThread().isInterrupted()) 
         break; 
       } 
       else 
       { 
        if (Thread.interrupted()) 
         break; 
       } 
      } 
      System.out.println("Nice shutdown"); 
      latch.countDown(); 
      return null; 
     } 
    }; 
    System.out.println("Task submitted"); 
    Future<Void> task = executor.submit(callable); 
    Thread.sleep(100); 
    task.cancel(true); 
    latch.await(); 
    System.out.println("Main exited"); 
    executor.shutdown(); 
} 
+0

No * siempre * no se detiene. – Jerome

+0

En mi máquina lo hace. – ripper234

+0

jerome, verifique la configuración del compilador ... tal vez esté usando una JVM anterior. – PaulP1975

Respuesta

4

Esto parece un known issue con máquinas con múltiples procesadores, principalmente en las versiones de SO y java 64 bits 1,5-7,0

A DESCRIPCIÓN DEL PROBLEMA: Mientras se ejecuta dos hilos simultáneos, el primer hilo interrumpe el el segundo usando Thread.interrupt(). El segundo hilo prueba si se ha interrumpido llamando al método Thread.isInterrupted() que siempre devuelve falso.

Esto ocurre en una computadora multiprocesador con sistema operativo de 64 bits (Vista y Linux). En Vista de 64 bits, esto ocurre cuando se utiliza una JVM de 64 bits (todas las versiones de la 1.5 a la 1.7), pero no ocurre cuando se utiliza una JVM de 32 bits. En Linux de 64 bits, esto ocurre cuando se utiliza una JVM de 64 bits (todas las versiones de 1.5 a 1.7) o cuando se utiliza una JVM de 32 bits (todas las versiones de la 1.5 a la 1.7).

La solución es instalar la versión con el arreglo, que es 1.6.0_16-b02 o posterior.

+0

Buena captura, pero el estado del error es "resuelto solucionado en hs16 (b04)". Esta es la versión que estoy ejecutando: versión java "1.6.0_14" Java (TM) SE Runtime Environment (compilación 1.6.0_14-b08) Java HotSpot (TM) 64-Bit Server VM (compilación 14.0-b16 , modo mixto) – ripper234

+0

O tal vez simplemente no entiendo los números de la versión de Java. ¿Se supone que el error está arreglado en el JDK que tengo? ¿Debo volver a abrirlo o descargar un nuevo JDK? – ripper234

+0

hs16 (b04) es la versión de punto caliente, no la versión de JRE. Parece que la solución está en 1.6.0_16-b02, que es posterior a su versión, por lo que debe descargar la última versión (1.6.0_17). – Mocky

0

ripper234, i acaba de ejecutar esto en mi máquina y siempre paradas no importa qué valor utilizo para las impresiones y qué interrupciones usar. Estoy usando jdk1.6.0_16. mirando el javadoc, tal vez tiene algo que ver con el hecho de que interrupted() borra el estado (interrumpido) después de cada llamada y no está interrumpido(). el hecho de que a veces funciona para jerome, siempre para mí y nunca (?) para que pudieras indicar una diferencia en los jdks que estamos usando O en la velocidad de nuestras máquinas. si tiene algo que ver con la limpieza del estado, eso podría explicar la variabilidad.