我正在使用一个外部库,它定义了一个接受Monitor
接口的Sensor
类,并定期将结果发送到它中:
public interface Sensor {
// called by the monitor when new results are available
void updatedResult(double result);
// called when done sending results
void done();
}
我已经按如下方式实现了传感器:
public class SensorImpl implements Sensor {
private boolean isDone;
private List<double> data;
public SensorImpl() {
this.isDone = false;
this.data = new ArrayList<>();
}
@Override
void updatedResult(double result);
this.data.add(result);
}
@Override
void done() {
this.isDone = true;
}
public boolean isDoneReceiving() {
return this.isDone;
}
public List<double> getData() {
return this.data;
}
}
我正在运行我的程序(简化):
public void run() {
// initialize a sensor instance
SensorImpl sensor = new SensorImpl();
// initialize a monitor that streams data into the sensor (async)
Monitor monitor = new Monitor(sensor);
// start monitoring the sensor
monitor.start();
// block until done
while (!sensor.isDoneReceiving()) {
Thread.sleep(50);
}
// retrieve data and continue processing...
List<double> data = sensor.getData();
// ...
}
虽然这有效,但是在睡眠时阻塞线程感觉很蠢,我正在寻找一种方法来使这个更干净。当应用执行器来并行监视各种类型的多个传感器时,这变得更加相关。任何帮助将不胜感激。
我最终实施了Future<List<Double>>
,这让我可以简单地调用List<Double> results = sensor.get();
,这会阻止所有结果可用。
public class SensorImpl implements Sensor {
// ...
private CountDownLatch countDownLatch;
public SensorImpl() {
this.countDownLatch = new CountDownLatch(1);
}
// ...
@Override
public void done() {
// when called by async processes, decrement the latch (and release it)
this.countDownLatch.countDown();
}
// ...
}
这是一个很好的答案,提供了很好的参考:https://stackoverflow.com/a/2180534/187907
答案 0 :(得分:1)
在您的情况下,concurrent
包中的几个类可以为您提供帮助,例如Semaphore
,CoundDownLatch
,CyclicBarrier
甚至是BlockingQueue
,其中你会阻塞队列并等待其他线程在完成时将值放入其中。
CountDownLatch最有可能最适合您的具体示例。 也许您可以查看this question,它对Semaphore和CountDownLatch有一个很好的概述: