Как потоки, которые полагаются друг на друга, обмениваются данными на Java?
Например, я создаю веб-искатель с потоками, которым нужны данные, поступающие из других потоков.
Как потоки, которые полагаются друг на друга, обмениваются данными на Java?
Например, я создаю веб-искатель с потоками, которым нужны данные, поступающие из других потоков.
Это зависит от характера общения.
и так далее.
Самая простая и наиболее рекомендуемая форма связи между потоками - это просто ожидание завершения других потоков. Это проще всего сделать с помощью Future
:
ExecutorService exec = Executors.newFixedThreadPool(50);
final Future f = exec.submit(task1);
exec.submit(new Runnable() {
@Override
public void run() {
f.get();
// do stuff
}
});
Второе задание не будет выполнено, пока не выполнится первое.
Java 5+ имеет много параллельных утилит для работы с такими вещами. Это может означать использование LinkedBlockingQueue
s, CountDownLatch
или многих, многих других.
Для углубленного изучения параллелизма Java Concurrency на практике необходимо прочитать.
Ниже приведен пример взаимодействия между потоками:
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]);
}
}
}
Взгляните на java.util.Observer/java.util.Observable. Они именно то, что вы ищете.
Вы можете использовать 2 ExecutorServices, передать реализацию Callable для службы A, которая знает, что нужно следовать в службе B. Когда Callable завершила работу, она отправляет новую задачу в службу B, которая делает что-то дополнительное с результатами.
Вы можете использовать CountDownLatch или какой-либо другой барьер, если вам нужно выполнить дополнительную работу, как только все элементы были обработаны в обеих службах.
ExecutorService api довольно прямолинейный, по большей части вы, вероятно, будете использовать что-то вроде .newFixedThreadPool(int threads) и передавать ему Runnables/Callables.