comunicación entre hilos en java

¿Cómo se comunican los hilos que dependen unos de otros en Java?

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

Eso depende de la naturaleza de la comunicación.

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

La forma más simple y recomendable de comunicación entre hilos es simplemente esperar la finalización de otros hilos. Eso se hace más fácilmente usando 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 la primera se complete.

Java 5+ tiene muchas utilidades simultáneas para manejar 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.

A continuación se muestra un ejemplo de comunicación entre hilos:

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

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

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

Podría usar CountDownLatch u otra barrera si necesita realizar trabajo adicional una vez que todos los artículos se hayan 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.