[英]Java8 - Converting an async interface into a synchronous one
我正在使用一個外部庫,該庫定義了一個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
在您的情況下, concurrent
CoundDownLatch
幾個類可以為您提供幫助,例如Semaphore
, CoundDownLatch
, CyclicBarrier
或BlockingQueue
,您可以在其中BlockingQueue
隊列,並在隊列結束時等待其他線程將值放入其中。
CountDownLatch最有可能最適合您的特定示例。 也許您可以查看此問題 ,它對Semaphore和CountDownLatch具有很好的概述:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.