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

时间:2017-01-31 21:42:59

标签: java multithreading asynchronous blocking thread-sleep

我正在使用一个外部库,它定义了一个接受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

1 个答案:

答案 0 :(得分:1)

在您的情况下,concurrent包中的几个类可以为您提供帮助,例如SemaphoreCoundDownLatchCyclicBarrier甚至是BlockingQueue,其中你会阻塞队列并等待其他线程在完成时将值放入其中。

CountDownLatch最有可能最适合您的具体示例。 也许您可以查看this question,它对Semaphore和CountDownLatch有一个很好的概述: