2017-01-31 15 views
0

я работаю с внешним Lib, который определяет Monitor класса, который принимает интерфейс Sensor и посылает результаты в нее периодически:Java8 - Преобразование интерфейса асинхронного в синхронный одном

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(); 

    // ... 
} 

В то время как это работает, кажется, что неприятно блокировать нить со сном, и я ищу способ сделать это чище. Это становится еще более актуальным при применении исполнителей для параллельного контроля нескольких датчиков разных типов. Любая помощь будет оценена по достоинству.

UPDATE:

я в конечном итоге реализации 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

+2

Сделайте 'Реализация done'' 'countDown' CountDownLatch' из 1. Сделайте свою' 'isDoneReceiving' реализацию await' на тот же' CountDownLatch '. –

ответ

1

В вашем случае, несколько классов из concurrent пакета может помочь вам, например, Semaphore, CoundDownLatch, CyclicBarrier или даже BlockingQueue, где бы блокировать очередь и ждать, пока другие потоки не будут вставлять в нее значения по завершении.

CountDownLatch наиболее вероятно подходит для вашего конкретного примера. Может быть, вы можете просматривать this question, имеет хороший обзор о Семафоре и CountDownLatch:

 Смежные вопросы

  • Нет связанных вопросов^_^