Шаблон реактора NIO: получение асинхронных обратных вызовов внутри цикла селектора каждые N миллисекунд - PullRequest
0 голосов
/ 16 февраля 2012

Мне было интересно, какова стандартная / лучшая реализация этого в Java NIO. Это принципиально важно для реализации чего-то вроде сердцебиения каждые N секунд и т. Д. Примечание. По очевидным причинам (потоки являются злыми, а переключение контекста медленным), все должно всегда происходить внутри цикла селектора.

Примечание 1: Ответ Apache MINA не учитывается, если только вы и структура не продемонстрируете четкий сценарий, в котором это делается в KISS (Keep It Простой Глупый) путь.

Примечание 2: Трубы требуют резьбы.

Ответы [ 2 ]

3 голосов
/ 17 февраля 2012

Не уверен, почему у вас не будет фонового потока для отправки тактовых импульсов или тайм-аута соединений.Сердцебиения обычно не считаются критичными для производительности.

Вы можете заставить селектор ждать определенное время и посылать сердцебиения и проверять интервалы времени.

Вы имеете в виду

selector.select(timeout);

if (System.currentTimeMS() > sendHeartbeatTime) {
    for(Connection conn: connections) 
        conn.checkAndSendHeartbeat();
}

// in Connection
private long lastSend = System.currentTimeMS();
private long lastRead = System.currentTimeMS();

public void writeData() {
   lastSend = System.currentTimeMS();
   // write data.
}

public void checkAndSendHeartbeat() {
   long now = System.currentTimeMS();
   if (now - lastRead > HEARTBEAT_TIMEOUT) {
      closeConnection();
   else if (now - lastSend > HEATBEAT_INTERVAL)
      writeHeartBeatData();
} 
2 голосов
/ 17 февраля 2012

создать канал, зарегистрировать конец читаемой трубы в селекторе, запланировать таймер, при обратном вызове таймера записать один байт в конец доступной для записи трубы. Обработчик ввода-вывода должен воспринимать событие, считываемое каналом, как триггерный сигнал.

...