How do threads that rely on one another communicate in Ja开发者_运维知识库va?
For example, I am building a web crawler with threads that need data that comes from other threads.
Below is example for Inter thread communication:
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]);
}
}
}
That depends on the nature of the communication.
- Is it duplex (ie A talks to B and B talks to A)?
- Is it communication of data or communication of completion?
and so on.
The simplest and most advisable form of inter-thread communication is simply to wait for the completion of other threads. That's most easily done by using Future
:
ExecutorService exec = Executors.newFixedThreadPool(50);
final Future f = exec.submit(task1);
exec.submit(new Runnable() {
@Override
public void run() {
f.get();
// do stuff
}
});
The second task won't execute until the first completes.
Java 5+ has many concurrent utilities for dealing with this kind of thing. This could mean using LinkedBlockingQueue
s, CountDownLatch
or many, many others.
For an in-depth examination of concurrency Java Concurrency in Practice is a must-read.
Take a look at java.util.Observer/java.util.Observable. They are exactly what you are looking for.
You could use 2 ExecutorServices, submit a Callable implementation to service A that knows about follow on service B. When the Callable has completed it's work, it submits a new task to service B that does something additional with the results.
You could use a CountDownLatch or some other barrier if you need to perform additional work once all items have been processed in both services.
The ExecutorService api is pretty straight forward, for the most part you'll probably be using something like .newFixedThreadPool(int threads) and submitting Runnables/Callables to it.
精彩评论