позволить одному потоку идти, другому ждать, а другие отбрасывать - PullRequest
2 голосов
/ 01 февраля 2012

У меня есть наблюдатель, которого можно вызвать несколько раз.Если метод onChange наблюдателя все еще выполняется, второй вызов должен подождать, и следующие вызовы должны игнорироваться.

Я использовал это:

Semaphore semaphore = new Semaphore(2,false);
...
public void onChange() {
    if (!semaphore.tryAcquire()) return;
    synchronized (semaphore) { 
        // do your stuff
        semaphore.release();
    }
}

Это нормально?Есть ли лучший способ?

Ответы [ 2 ]

1 голос
/ 01 февраля 2012

Ваша логика выглядит хорошо для меня.Насколько я понимаю, 2 темы смогут получить Semaphore в любом порядке.Любые другие потоки, пытающиеся получить данные, вернутся и будут проигнорированы.

Первый поток, который сделает synchronized, заблокирует другой, поэтому будет работать только один поток, а один (макс.) Будет ожидать.Как только задание будет завершено и будет вызван release(), в семафор будет добавлен другой поток.Как только блок synchronized завершится, первый ожидающий поток начнет работать.

Другой способ сделать это - два объекта Semaphore, в то время как второй объект делает acquire вместоtryAcquire.Но ваш путь должен работать.

Как указал @herschel, я бы сделал try/finally вокруг "делай свое дело", чтобы гарантировать освобождение семафора.Что-то вроде:

...
synchronized (semaphore) {
    try {
        // do your stuff
    } finally {
        semaphore.release();
    }
}
0 голосов
/ 01 февраля 2012

В конструкторе должно быть true вместо false, иначе порядок не всегда соблюдается

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...