Блоки потока Java при регистрации канала в селекторе, в то время как выбор () называют. Что сделать?

UML-диаграммы сильно переоценены

Конечно, есть полезные диаграммы, например. Диаграмма классов для Composite Pattern , но многие диаграммы UML не имеют абсолютно никакого значения.

14
задан Flow 27 March 2018 в 20:17
поделиться

3 ответа

Вы пытались распечатать трассировку стека всех потоков в вашей программе? (с помощью kill -QUIT в Unix или Ctrl + Break в Windows или с помощью утилиты jstack )?

AbstractSelectableChannel содержит блокировку, для которой configureBlocking и регистр необходимо синхронизировать. Эта блокировка также доступна через метод blockingLock () , и поэтому другой поток потенциально может удерживать блокировку, вызывая блокировку вашего вызова регистра на неопределенный срок (но без трассировки стека это трудно сказать).

0
ответ дан 1 December 2019 в 06:28
поделиться

You need to use a lock and manually synchronize.

In the same thread you are running the selector loop have a ReentrantLock:

final ReentrantLock selectorLock = new ReentrantLock();

Then when you need to register with the selector do something like this:

selectorLock.lock();
try {
    selector.wakeup();
    socketChannel.register(selector, ops);
} finally {
    selectorLock.unlock();
}

Finally, during your loop that you are calling accept(), something like this:

selectorLock.lock();
selectorLock.unlock();

selector.select(500);

And then continue on with the rest of your logic.

This construct guarantees that the register() call will not block by ensuring that there is never another select() between corresponding wakeup() and register() calls.

11
ответ дан 1 December 2019 в 06:28
поделиться

Это является основной особенностью большинства реализаций NIO, которые не очевидно из документации.

Вы должны сделать все регистрационные звонки из того же потока, который выполняет ваш выбор или тупики. Обычно это делается, предоставив очередь регистраций / израсходов / изменений процентов, которые записываются, и затем SELECTOR.Wakeup () называется. Когда выбирающая нить просыпается, она проверяет очередь и выполняет любые запрошенные операции.

36
ответ дан 1 December 2019 в 06:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: