简体   繁体   English

Java8-将异步接口转换为同步接口

[英]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. 任何帮助将不胜感激。

UPDATE: 更新:

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几个类可以为您提供帮助,例如SemaphoreCoundDownLatchCyclicBarrierBlockingQueue ,您可以在其中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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM