2010-01-31 25 views
25

¿Cómo se comunican en Java los subprocesos que dependen el uno del otro?comunicación entre subprocesos en java

Por ejemplo, estoy construyendo un rastreador web con hilos que necesitan datos que provienen de otros hilos.

Respuesta

20

Eso depende de la naturaleza de la comunicación.

  • ¿Es dúplex (es decir, A habla con B y B habla con A)?
  • ¿Es la comunicación de datos o comunicación de finalización?
  • y así sucesivamente.

La forma más simple y más recomendable de comunicación entre hilos es simplemente esperar la finalización de otros hilos. Eso se hace más fácilmente mediante el uso de Future:

ExecutorService exec = Executors.newFixedThreadPool(50); 
final Future f = exec.submit(task1); 
exec.submit(new Runnable() { 
    @Override 
    public void run() { 
     f.get(); 
     // do stuff 
    } 
}); 

La segunda tarea no se ejecutará hasta que se complete la primera.

Java 5+ tiene muchas utilidades concurrentes para hacer frente a este tipo de cosas. Esto podría significar el uso de LinkedBlockingQueue s, CountDownLatch o muchos, muchos otros.

Para un examen en profundidad de concurrencia Java Concurrency in Practice es una lectura obligada.

+0

Los hilos no van en ambos sentidos, espera un hilo para el resultado de otro, pero no viceversa. Es cierto que estoy un poco intimidado por el uso de ExecutorService y Future, ya que nunca he oído hablar de ellos antes. ¿Hay algún otro método de comunicación entre puntos que no use Future and ExecutorService? – tipu

+1

No hay necesidad de sentirse intimidado por 'ExecutorService' y' Future'. Son razonablemente simples y deben tomar menos de 2 horas para aprender. Usar 'Future's es más fácil que las clases de cola estándar, y mucho más fácil que rodar tus propias clases de cola usando' wait() 'y' notify() '. – finnw

+0

@cletus, -1 para llamar a 'Future.get()' dentro de una tarea en un grupo de hilos * fixed *. El peligro debería ser obvio. – finnw

2

Eche un vistazo a java.util.Observer /java.util.Observable. Son exactamente lo que estás buscando.

+5

El uso de observadores no funcionará, ya que no cruzan hilos (todas las devoluciones de llamada del Observador se invocarán desde el hilo del Observable). "Tenga en cuenta que este mecanismo de notificación no tiene nada que ver con los hilos". desde http://docs.oracle.com/javase/6/docs/api/java/util/Observable.html –

0

Puede utilizar 2 ExecutorServices, enviar una implementación invocable al servicio A que sabe acerca del seguimiento del servicio B. Cuando el Callable ha completado su trabajo, envía una nueva tarea al servicio B que hace algo adicional con los resultados.

Puede usar un CountDownLatch u otra barrera si necesita realizar trabajo adicional una vez que todos los artículos se han procesado en ambos servicios.

La aplicación ExecutorService es bastante sencilla, en su mayor parte probablemente uses algo como .newFixedThreadPool (int threads) y le envíes Runnables/Callables.

23

A continuación es un ejemplo para la comunicación entre el hilo:

public class Main { 
    public static void main(String[] args) { 
     Chat m = new Chat(); 
     new T1(m); 
     new T2(m); 
    } 
} 

class Chat { 
    boolean flag = false; 

    public synchronized void FromSam(String msg) { 
     if (flag) { 
      try { 
       wait(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
     System.out.println(msg); 
     flag = true; 
     notify(); 
    } 

    public synchronized void FromJam(String msg) { 
     if (!flag) { 
      try { 
       wait(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     System.out.println(msg); 
     flag = false; 
     notify(); 
    } 
} 

class T1 implements Runnable { 
    Chat m; 
    String[] s1 = { "Hello Jam", "How are you ?", "I am also doing fine!" }; 

    public T1(Chat m1) { 
     this.m = m1; 
     new Thread(this, "Sam").start(); 
    } 

    public void run() { 
     for (int i = 0; i < s1.length; i++) { 
      m.FromSam(s1[i]); 
     } 
    } 
} 

class T2 implements Runnable { 
    Chat m; 
    String[] s2 = { "HI Sam", "I am good,And U ?", "ha haa" }; 

    public T2(Chat m2) { 
     this.m = m2; 
     new Thread(this, "Jam").start(); 
    } 

    public void run() { 
     for (int i = 0; i < s2.length; i++) { 
      m.FromJam(s2[i]); 
     } 
    } 
} 
+0

Este ejemplo se usa aquí: [http://www.tutorialspoint.com] (http: // www .tutorialspoint.com/java/java_thread_communication.htm) –