等待事件/更新的最佳方式是什么。例如,我正在等待在执行某些操作之前更新此数据结构。在循环中实现它并不是最好的方法,因为它消耗了大量的CPU时间,如:
while (true) {
// keep checking the data structure
// if data structure is updated
// break;
}
// do something here
在Java中实现类似这样的东西的简单但有效的方法是什么?
答案 0 :(得分:1)
这实际上取决于程序其余部分的结构。我可能会先查看java.util.concurrent,看看那里的东西是否适合你。
您可以这样做的示例:
期货 - 如果你有一些“工作”要做,你可以有一个线程池执行者服务来执行工作。当您致电submit()来完成工作时,您将获得一个可以检查或阻止的未来,直到工作完成。
队列 - 如果您有一个组件正在完成工作而一个组件正在进行等待,您可以使用队列进行通信。任何时候完成数据处理,它都可以添加到队列中。您可以使用LinkedBlockingQueue和poll()来完成工作。
监听器 - 根本没有并发,你可以使用监听器/观察者模式。
根据您的应用程序结构,有许多不同的选项。
答案 1 :(得分:1)
wait-notifyAll比循环更有效。
wait()的标准习语:
synchronized (obj) {
while(condition not hold)
obj.wait();
}
但是这是控制线程的原始方法,你最好使用java.util.concurrent
包中的类。而且,如果我遇到这样的问题,我会选择Chris Dail的答案。
答案 2 :(得分:0)
这是我会做的代码示例。
在这个逻辑中,我在线程中使用join
方法。这确保在继续执行主线程之前连接所有线程。我已将TODO用于您需要添加代码的位置
import java.util.ArrayList;
import java.util.List;
public class MultiThread extends Thread{
public void run() {
System.out.println("Starting Thread - " + this.getName()+this.getThreadGroup());
//TODO data structure is updated here
}
public static void main(String[] args) {
List dataStructureList = new ArrayList() ;//TODO need to replace with list of data structure
//TODO dataStructureList contain list of items
Thread[] threadArr = new Thread[dataStructureList.size()];
for (int j = 0; j < threadArr.length; j++) {
threadArr[j] = new MultiThread();
threadArr[j].setName("Thread " + j);
threadArr[j].start();
}
try {
for (int j = 0; j < threadArr.length; j++) {
threadArr[j].join();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("All thread finished");
//TODO do something here
}
}
答案 3 :(得分:0)
假设您在应用程序中使用多线程。要使用具有多个线程的一个对象,您应该使用同步。当一个线程初始化数据结构时,其他线程等待完成初始化。这个逻辑通常使用wait / notify方法实现,可以在任何对象上调用。
工作线程:
while (initialized) {
synchronized (object) {
object.wait();
}
}
初始化线程:
synchronized (object) {
// initialization
initialized = true;
object.notifyAll();
}
object
是应该初始化的数据结构。 initialized
标志用于指示初始化已完成。最好使用此标记,因为有时wait
可以在没有对应notify
的情况下完成。