【问题标题】:Java8 - Converting an async interface into a synchronous oneJava8 - 将异步接口转换为同步接口
【发布时间】: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&lt;List&lt;Double&gt;&gt;,它允许我简单地调用List&lt;Double&gt; 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


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2020-10-18
    • 2016-01-01
    • 2018-11-04
    • 2012-11-14
    • 2013-01-05
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多