2010-12-09 25 views
6

he implementado una interfaz Runnable para cargar los mosaicos de imágenes y quiero llamar al hilo principal desde este hilo secundario para mostrar los mosaicos. ¿alguien puede decirme cómo llamar a un hilo principal desde un subproceso de interfaz ejecutable en Java.llamando al hilo principal desde el hilo Runnable en java

gracias.

+0

En general, es un buen diseño para llamar a otros hilos desde el hilo principal. –

+0

@ org.life.java, ¿qué quiere decir usted (y OP) cuando dice "llamar a otro hilo"? – aioobe

+0

@aioobe Creo que OP quiere llamar al hilo principal desde otro hilo iniciado desde main. algo como http://ideone.com/G8gLN –

Respuesta

4

En lugar de Runnable puede usar Callable<Set<Image>> que devuelve un conjunto de imágenes cargadas. Envíe esta tarea invocable a un ejecutor, obtenga el Future<Set<Image>> y espere a que el hilo de carga finalice su trabajo.

Por ejemplo:

Future<Set<Image>> future = 
    Executors.newSingleThreadExecutor().submit(new Callable<Set<Image>>() 
    { 
     @Override 
     public Set<Image> call() throws Exception 
     { 
     return someServiceThatLoadsImages.load(); 
     } 
    }); 

try 
{ 
    Set<Image> images = future.get(); 
    display(images); 
} catch (Exception e) 
{ 
    logger.error("Something bad happened", e); 
} 
+0

+1 Interesante. – Favonius

+0

. Compruébelo ahora ... 7135 -> 7145 :) – Favonius

+0

+1 Muy buena idea – dimitrisli

0

¿Qué quiere decir con "invocar un hilo"?

Probablemente desee de alguna manera "notificar" al hilo principal que las imágenes han sido cargadas. Usted podría esto, por ejemplo, dejando que el hilo principal wait() para el hilo de carga notify() lo que las imágenes se han cargado.

Preferiblemente, sin embargo, debe utilizar una de las clases de concurrencia más "de alto nivel" en el paquete java.util.concurrent. Por ejemplo, Callable y Future según lo sugerido por Boris Pavlović. Hay un uso de muestra en the documentation of Future.

0

realmente no se puede "llamar" un hilo de otro. Lo que puede hacer es tener una cola de mensajes: el hilo secundario pondría mensajes en la cola y el hilo principal los levantaría de la cola y procesaría.

+0

Sí, en Java esto se puede hacer con un BlockingQueue y llamando a BlockingQueue.take() o BlockingQueue.poll(). Mucha gente usa un ExecutorService para administrar todo esto. –

-1

Creo que por "invocar el hilo" el autor quiso decir algún tipo de devolución de llamada desde el hilo de trabajo al hilo principal para notificarlo sobre algún tipo de evento.

Hay muchas maneras de implementar ese tipo de devolución de llamada, pero utilizaría una interfaz de escucha simple. Algo como esto:

//Interface of the listener that listens to image load events 
public interface ImageLoadListener { 
void onImageLoadSuccess(ImageInformation image); 
void onImageLoadFailed(ImageInformation image); 
} 

//Worker thread that loads images and notifies the listener about success 
public class ImageLoader implements Runnable { 
private final ImageLoadListener loadListener; 
public ImageLoader(ImageLoadListener listener) { 
    this.loadListener = listener; 
} 

public void run() { 
    .... 
    for (each image to load) { 
    .... 
    if (load(image)) { 
    if (loadListener != null) { 
    loadListener.onImageLoadSuccess(image); 
    } 
    } else { 
    if (loadListener != null) { 
    loadListener.onImageLoadFailed(image); 
    } 
    } 
    } 
} 
} 

//Main class that creates working threads and processes loaded images 
public class MainClass { 
... 

//Main method for processing loaded image 
void showImageAfterLoad(ImageInformation information) { 
    ... 
} 

//Some button that should create the worker thread 
void onSomeButtonClick() { 
    //Instantiate the listener interface. If image load is successful - run showImageAfterLoad function on MainClass 
    ImageLoadListener listener = new ImageLoadListener() { 
    void onImageLoadSuccess(ImageInformation image) { 
    MainClass.this.showImageAfterLoad(image); 
    } 
    void onImageLoadFailed(ImageInformation image) { 
    //Do nothing 
    } 
    }; 

    //Create loader and it's thread 
    ImageLoader loader = new ImageLoader(listener); 
    new Thread(loader).start(); 
} 
} 

En caso de que necesite que sea escalable, te recomiendo que cambiar a alguna implementación del patrón de bus de eventos. Por ejemplo: http://code.google.com/p/simpleeventbus/

El bus de eventos es generalmente lo mismo que escribí en mi ejemplo, pero es muy escalable. La principal diferencia es que puede administrar varios tipos de eventos y registrar muchos oyentes a la vez.

+2

-1 según la declaración de apertura. La "devolución de llamada" en realidad no se ejecuta en el "hilo principal" en su ejemplo, sino en la nueva instancia de subproceso que se inició. –

+0

@Tim Bender: la instrucción de apertura no tiene la palabra "ejecutar" en ninguna parte. Sin embargo, el autor pregunta por una forma de "llamar" el hilo. "Llamar" puede ser cualquier cosa, desde ejecutar el hilo tal como lo entendió, hasta proporcionarle algunos datos para que pueda usarlo para algunos cálculos, tal como lo entendí. – bezmax

+0

No hay problema con esta respuesta: es más flexible (lo que si quiero hacer informes provisionales, como el progreso, pero tengo otras razones para evitar SwingWorker), y es, de hecho, la manera en que leo la pregunta original. También proporciona un ejemplo de Listener genérico sin tener que rastrear los millones de muestras de ActionListener. – gbryant

Cuestiones relacionadas