@Override
    public void run() {
        try {
            // Создаём Selector
            Selector selector = SelectorProvider.provider().openSelector();
            // Открываем серверный канал
            ServerSocketChannel serverChannel = ServerSocketChannel.open();
            // Убираем блокировку
            serverChannel.configureBlocking(false);
            // Вешаемся на порт
            serverChannel.socket().bind(new InetSocketAddress(host, port));
            // Регистрация в селекторе
            serverChannel.register(selector, serverChannel.validOps());
            // Основной цикл работу неблокирующего сервер
            // Этот цикл будет одинаковым для практически любого неблокирующего
            // сервера
            while (selector.select() > -1) {
                // Получаем ключи на которых произошли события в момент
                // последней выборки
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    if (key.isValid()) {
                        // Обработка всех возможнных событий ключа
                        try {
                            if (key.isAcceptable()) {
                                // Принимаем соединение
                                accept(key);
                            } else if (key.isConnectable()) {
                                // Устанавливаем соединение
                                connect(key);
                            } else if (key.isReadable()) {
                                // Читаем данные
                                read(key);
                            } else if (key.isWritable()) {
                                // Пишем данные
                                write(key);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            close(key);
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalStateException(e);
        }
    }