2010-06-29 5 views
41

Digamos que tenemos este sencillo ejemplo:¿Cómo puede un subproceso devolver un valor después de terminar su trabajo?

public Example extends Thread{ 

    String temp;  

    public Example(){ 
    } 

    @Override 
    public void run(){ 
     . 
     . 
     . 
     . 
     temp = "a_value"; 
    } 

    public static void main(String[] args) { 

     Example th = new Example(); 
     th.start(); 
    } 

} 

¿Cómo puede el hilo después de terminar su trabajo me devuelva la temperatura de cuerdas?

+1

Debería ser 'th.start()'. Y usted implementó una de las formas de devolver un valor desde el hilo. –

Respuesta

7

Puede lograr esto mediante el patrón Observer. al finalizar el hilo notifica a todos los oyentes que está terminado y que pueden recuperar el valor (a través de un getter). O incluso puede enviar el valor calculado.

O puede utilizar una tarea, consulte FutureTask, un ejecutable (de hecho, como se indica a continuación en una llamada) que devuelve un resultado y puede arrojar excepciones.

11

Mire Future interfaz javadoc. Tiene un uso de muestra que le muestra cómo hacer esto.

63

Hacer uso de la (relativamente) nueva Callable<T> en lugar de Ejecutable (disponible en 1.5 y versiones más recientes):

Aquí está una (simple) ejemplo:

import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 


public class Main { 

    public static void main(final String[] argv) { 
     final ExecutorService service; 
     final Future<String> task; 

     service = Executors.newFixedThreadPool(1);   
     task = service.submit(new Foo()); 

     try { 
      final String str; 

      // waits the 10 seconds for the Callable.call to finish. 
      str = task.get(); // this raises ExecutionException if thread dies 
      System.out.println(str); 
     } catch(final InterruptedException ex) { 
      ex.printStackTrace(); 
     } catch(final ExecutionException ex) { 
      ex.printStackTrace(); 
     } 

     service.shutdownNow(); 
    } 
} 

class Foo implements Callable<String> { 
    public String call() { 
     try { 
      // sleep for 10 seconds 
      Thread.sleep(10 * 1000); 
     } catch(final InterruptedException ex) { 
      ex.printStackTrace(); 
     } 

     return ("Hello, World!"); 
    } 
} 
+2

"(relativamente) nuevo" ¿Con respecto a qué? Fue introducido en una versión que ahora ha completado su período de fin de vida útil. –

+20

En relación con las versiones ... 1.6 es actual, se lanzó en 1.5. Compare eso con Thread que estaba en 1.0 ... muchos de los libros que los estudiantes aprenden no tienen Callable en él. – TofuBeer

+7

como siempre en ejemplos dejé preguntándome wtf es foo – jiduvah

0

Si usted no quiere para intercambiar la solución para utilizar objetos invocables, puede usar también colas y devolver el resultado de los hilos de esa manera.
que re-escribió su ejemplo como este:

import java.util.PriorityQueue; 
import java.util.Queue; 

public class GetResultFromThread { 
    public static void main(String[] args) throws Exception { 
     Queue<String> queue = new PriorityQueue<String>(); 
     int expectedResults = 2; 
     for (int i = 0; i < expectedResults; i++) { 
      new Example(queue).start(); 
     } 

     int receivedResults = 0; 
     while (receivedResults < expectedResults) { 
      if (!queue.isEmpty()) { 
       System.out.println(queue.poll()); 
       receivedResults++; 
      } 
      Thread.sleep(1000); 
     } 
    } 
} 

class Example extends Thread { 
    private final Queue<String> results; 

    public Example(Queue<String> results) { 
     this.results = results; 
    } 

    @Override 
    public void run() { 
     results.add("result from thread"); 
    } 
} 

Tenga en cuenta que deberá pensar en la sincronización y la simultaneidad!

+3

En lugar de simplemente hacer clic en la flecha hacia abajo y decir que es una mala solución, sería bueno si explica por qué. Gracias – thomasb

+0

En realidad yo esta @ la solución de Martin es muy inteligente, gracias por eso – Benvorth

Cuestiones relacionadas