Селектор NIO активируется немедленно и не блокируется при выборе (). Неуправляемая вращающаяся петля - PullRequest
0 голосов
/ 14 октября 2011

У меня есть поток селектора: http://www.copypastecode.com/83442/

У него есть список запросов на изменение, которые он обрабатывает, затем блокирует, затем обрабатывает ключи.Методы connect и send являются единственными, которые отправляют wakeup () в селектор.

Когда я устанавливаю 2 сервера и запускаю отдельные циклы select, бывает, что 2-й сервер не блокируется при выборе (),Я говорю об этом, потому что сообщения журнала не распечатываются ни при соединении, ни при отправке, а при обработке ключей.При бесконечном цикле никакие ключи не обрабатываются.

Как я могу исправить эту ситуацию?Если побеждает цель использования неблокирующего ввода-вывода.

protected void startSelectorThread() {
    new Thread() {
        public void run() {
            log.debug("NIOThreadedConnection: Selector Thread started; " + serverSocketChannel);
            selectorRunning = true;
            while (selectorRunning == true) {
                log.debug(".");
                processChangeRequests();
                blockForSelectorTraffic();
                processSelectionKeys();
            }
            System.out.println("Selector Thread terminated");
            nioServer.stoppedListening(null);
        }
    }.start();
}


protected void processChangeRequests() {
    synchronized (pendingChanges) {
        for(ChangeRequest change:pendingChanges) {
            switch (change.type) {
                case ChangeRequest.CHANGEOPS: {
                    SelectionKey key = change.socket.keyFor(socketSelector);
                    if (key == null) {
                        continue;
                    }
                    key.interestOps(change.ops);
                    continue;
                }
                // Client only:
                case ChangeRequest.REGISTER: {
                    try {
                        log.debug("future connection with channel: " + change.socket);
                        change.socket.register(socketSelector, change.ops);
                    } catch (ClosedChannelException e) {
                        log.debug("closed channel(" + change.socket + ")");
                    }
                    continue;
                }
            }
        }
        pendingChanges.clear();
    }
}


protected void blockForSelectorTraffic() {
    try {
        socketSelector.select();
    } catch (IOException e) {
        e.printStackTrace();
    }
}


protected void processSelectionKeys() {
    Iterator<SelectionKey> selectedKeys = socketSelector.selectedKeys().iterator();
    while (selectedKeys.hasNext()) {
        SelectionKey key = selectedKeys.next();
        log.debug("found a key: " + key);
        selectedKeys.remove();
        if (!key.isValid()) {
            log.debug("key invalid: " + key);
            continue;
        }
        try {
            if (key.isAcceptable()) {
                log.debug("accept with a ListenConnection: " + key);
                try {
                    accept(key);
                } catch (ClosedChannelException e) {
                    log.debug("closed server channel(" + key + ")");
                }
            } else if (key.isConnectable()) {
                log.debug("finishing connection: " + key);
                finishConnection(key);
            } else if (key.isReadable()) {
                log.debug("reading with key: " + key);
                int bytesRead = read(key);
                log.debug("read: " + bytesRead + " with key: " + key);
            } else if (key.isWritable()) {
                log.debug("writing with key: " + key);
                int bytesWritten = write(key);
                log.debug("write: " + bytesWritten + " with key: " + key);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    log.debug("all done with keys");
}

Спасибо, Роберт

...