Изменен ли этот объект в потоке-обработчике слушателя? - PullRequest
0 голосов
/ 27 августа 2018

В следующем фрагменте предположим, что два потока считывают / записывают из / в results. Когда поток eventListener пишет в results, сможет ли заблокированный поток получить доступ к последним результатам? Если нет, то какая утилита (volatile, AtomicReference) поможет?

private Object doStuff() {

    CountDownLatch latch = new CountDownLatch( 1 );
    Object[] results = new Object[1];

    EventObjectListener eventListener = ( String topic, Object eventObject ) -> {
        results[0] = eventObject;
        latch.countDown();
    };

    eventReceiver.addEventListener( eventListener );

    doThingThatGeneratesEvent();

    int waitMagnitude = 10;
    TimeUnit waitUnit = TimeUnit.SECONDS;
    try {
        latch.await( waitMagnitude, waitUnit );
    } catch ( InterruptedException e ) {
        return null;
    } finally {
        eventReceiver.removeEventListener( eventListener );
    }

    return results[0];
}

1 Ответ

0 голосов
/ 27 августа 2018

Да, CountDownLatch гарантирует видимость¹, поэтому, если await не истечет время ожидания, results[0] будет хорошо. Однако код, вероятно, можно было бы переписать, чтобы он был немного понятнее.

¹ т.е. все записи из потока до того, как countDown() произойдет до того, как другой поток вернется из вызова await().


A немного Более четкая (ИМХО) версия будет использовать CompletableFuture следующим образом:

CompletableFuture<Object> future = new CompletableFuture();

EventObjectListener eventListener = (topic, eventObject) -> 
        future.complete(eventObject);

try {
    return future.get(waitMagnitude, waitUnit);
} catch(Exception e) {
    return null;
} finally {
    eventReceiver.removeEventListener(eventListener);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...