【发布时间】:2017-01-31 21:42:58
【问题描述】:
我正在使用一个外部库,该库定义了一个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
【问题讨论】:
-
将您的
done实现countDown设为1 的CountDownLatch。将您的isDoneReceiving实现await设置在同一个CountDownLatch上。
标签: java multithreading asynchronous blocking thread-sleep