[英]Java8 - Converting an async interface into a synchronous one
I am working with an external lib that defines a Monitor
class that accepts a Sensor
interface and sends results into it periodically: 我正在使用一个外部库,该库定义了一个
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();
}
I have implemented the sensor as follows: 我已经实现了如下传感器:
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;
}
}
And am running my program like this (simplified): 并且正在像这样运行我的程序(简体):
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();
// ...
}
While this works, it feels icky to be blocking on a thread with sleep, and I'm looking for a way to make this cleaner. 尽管此方法有效,但是在睡眠中阻塞线程感觉很棘手,我正在寻找一种方法来使这种清洁器更清洁。 This becomes even more relevant when applying executors to monitor multiple sensors of various types in parallel.
当应用执行程序并行监视各种类型的多个传感器时,这一点变得更加重要。 Any assistance will be appreciated.
任何帮助将不胜感激。
I ended up implementing Future<List<Double>>
, which allowed me to simply call List<Double> results = sensor.get();
我最终实现了
Future<List<Double>>
,这使我可以简单地调用List<Double> results = sensor.get();
, which blocks until all results are available. ,直到所有结果都可用为止。
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();
}
// ...
}
Here's a great answer that provided good reference: https://stackoverflow.com/a/2180534/187907 这是一个很好的答案,提供了很好的参考: https : //stackoverflow.com/a/2180534/187907
In your case, several classes from the concurrent
package can help you, such as Semaphore
, CoundDownLatch
, CyclicBarrier
or even a BlockingQueue
, where you would block on the queue and wait for the other threads to put values in it when finished. 在您的情况下,
concurrent
CoundDownLatch
几个类可以为您提供帮助,例如Semaphore
, CoundDownLatch
, CyclicBarrier
或BlockingQueue
,您可以在其中BlockingQueue
队列,并在队列结束时等待其他线程将值放入其中。
A CountDownLatch is most probably best suited for your specific example. CountDownLatch最有可能最适合您的特定示例。 Perhaps you can view this question , it has a nice overview about Semaphore and CountDownLatch:
也许您可以查看此问题 ,它对Semaphore和CountDownLatch具有很好的概述:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.