【发布时间】:2011-01-11 08:21:00
【问题描述】:
相互依赖的线程如何在 Java 中进行通信?
例如,我正在构建一个带有线程的网络爬虫,这些线程需要来自其他线程的数据。
【问题讨论】:
标签: java multithreading
相互依赖的线程如何在 Java 中进行通信?
例如,我正在构建一个带有线程的网络爬虫,这些线程需要来自其他线程的数据。
【问题讨论】:
标签: java multithreading
这取决于沟通的性质。
等等。
线程间通信最简单和最可取的形式就是等待其他线程完成。使用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+ 有许多 并发实用程序来处理这类事情。这可能意味着使用LinkedBlockingQueues、CountDownLatch 或许多其他的。
对于并发性的深入检查,Java Concurrency in Practice 是必读的。
【讨论】:
ExecutorService 和Future 吓倒。它们相当简单,学习时间应该不到 2 小时。使用Futures 比标准队列类更容易,并且比使用wait() 和notify() 滚动您自己的队列类容易得多。
Future.get()。那里的危险应该是显而易见的。
看看java.util.Observer/java.util.Observable。 它们正是您正在寻找的。
【讨论】:
您可以使用 2 个 ExecutorServices,向服务 A 提交一个 Callable 实现,该实现知道服务 B 的后续操作。当 Callable 完成工作后,它会向服务 B 提交一个新任务,该任务对结果进行额外处理。
如果您需要在两个服务中处理完所有项目后执行额外的工作,您可以使用 CountDownLatch 或其他一些障碍。
ExecutorService api 非常简单,在大多数情况下,您可能会使用 .newFixedThreadPool(int threads) 之类的东西并向其提交 Runnables/Callables。
【讨论】:
以下是线程间通信的示例:
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]);
}
}
}
【讨论】: