análisis java NIO y comprensión básica de la utilización de

Me hace algún tiempo un blog red de programación Java - multi-hilo datos paralelos transceptor resume la práctica paralela transceptor entre el servidor y el cliente. El principio es muy simple, es decir, para un único cliente, el alcance del servicio dos hilos son responsables de las operaciones de lectura y escritura, luego pase permanece bloqueado esperando a leer y escribir ejecución.

De hecho, este modelo es muy mala. Debido a que cada cliente en las necesidades de los servidores para ocupar dos hilos, si hay 1000 clientes, es necesario 2000 + hilos. CPU necesita mucho tiempo para enhebrar cambios de contexto, se desperdician los recursos del sistema.

Queremos reducir el número de hilos, en primer lugar resolver el problema de bloqueo. El NIO puede ser multiplexado bloqueará lectura y escritura al borrado por IO. Junto con el grupo de subprocesos, se puede lograr el millón de conexiones de cliente con una pequeña cantidad de apoyo de la rosca.

¿Cuál es el NIO

NIO y IO multiplexación

Java NIO nombre completo de Java no bloqueo IO. Es decir, literalmente, no bloqueante IO. De hecho, el único no-bloqueo argumento aquí macro.

Acerca del modo de IO, donde otros citan un blog, describe las diferencias de varias modo IO:

Informar IO síncrona, asíncrona IO, bloqueando las conexiones y diferencias entre IO, sin bloqueo IO

Este blog no se repetirá estos, solo quiero decir NIO pertenecen a uno de los modelos multiplexación IO. (Lab tiene una espalda "UNIX Network Programming" a la escuela para poner fin a la epidemia debe echar un vistazo a esta parte)

Multiplexado modelo IP, hay un hilo para seguir sondear múltiples estados de socket cuando la toma de lectura y escritura de los acontecimientos, sólo para llamar a las operaciones de IO. Debido a que es un hilo para manejar toma de corriente múltiple, el sistema no necesita crear otro hilo, hilo de mantenimiento, sólo se toma cuando esté listo, utilizará los recursos IO, lo que reduce significativamente el consumo de recursos.

java NIO si hay cualquier uso selector.select () monitor de múltiples canales para llegar al evento, ningún evento ha sido bloqueado, un evento se llama procesamiento IO.

tres núcleos

  • Channel (Canal)
  • Buffer (Buffer)
  • Selector (los selectores)

Los detalles son como sigue
imagen

Ejemplo de aplicación NIO

Aquí se lee el mensaje del cliente al proceso del servidor, por ejemplo, describe el uso de NIO (contenido completo solamente de entrada, independientemente de la salida, por el momento). Dibuje un diagrama de flujo como se muestra a continuación:
imagen

  1. Y el establecimiento de un selector ServerSocketChannel, y el registro, las escuchas cliente para una solicitud de conexión de unión, de la siguiente manera:
selector = Selector.open();
ServerSocketChannel server = ServerSocketChannel.open();
// 设置为非阻塞
server.configureBlocking(false);
// 绑定本地端口
server.socket().bind(new InetSocketAddress(port));
// 注册客户端连接到达监听
server.register(selector, SelectionKey.OP_ACCEPT);

Sino también para establecer readSelector y writeSelector. De hecho, el grupo de subprocesos se establece de antemano, no escriba aquí por el momento.

readSelector = Selector.open();
writeSelector = Selector.open();
  1. Supervisar el canal, darle al cliente, y establecer el SocketChannel, para el seguimiento de los mensajes de cliente posteriores
//select()方法返回已就绪的通道数
if (selector.select() == 0) {
    continue;
}

Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {

    SelectionKey key = iterator.next();
    iterator.remove();

    // 检查当前Key的状态是否是accept的
    // 客户端到达状态
    if (key.isAcceptable()) {
        ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
        // 非阻塞状态拿到客户端连接
        SocketChannel socketChannel = serverSocketChannel.accept();

        try {
            // 客户端构建异步线程
            // 添加同步处理
            //此处代码暂且忽略
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("客户端连接异常:" + e.getMessage());
        }
    }
  1. El SocketChannel registrado en readSelector y writeSelector
/**
*参数分别是:channel,对应的selector,以及
*registerOps:待注册的操作集,这个在后文中有详细解析;
*locker:用于标识同步代码块的状态,是锁定还是可用;
*runnable:执行具体读写操作的类,送给线程池执行;
*map:建立SelectionKey与Runnable映射关系的HashMap。
*/
private static SelectionKey registerSelection(SocketChannel channel, Selector selector,
                                                  int registerOps, AtomicBoolean locker,
                                                  HashMap<SelectionKey, Runnable> map,
                                                  Runnable runnable) {
    synchronized (locker) {
    // 设置锁定状态
    locker.set(true);
    
    try {
        // 唤醒当前的selector,让selector不处于select()状态
        //注册channel时一定要将selector唤醒,否则当前select中没有刚注册的channel
        selector.wakeup();
    
        SelectionKey key = null;
        if (channel.isRegistered()) {
            // 查询是否已经注册过
            key = channel.keyFor(selector);
            if (key != null) {
            //将新的Ops添加进去
                key.interestOps(key.readyOps() | registerOps);
            }
        }
    
        if (key == null) {
            // 注册selector得到Key
            key = channel.register(selector, registerOps);
            // 注册回调
            map.put(key, runnable);
        }
    
        return key;
    } catch (ClosedChannelException e) {
        return null;
    } finally {
        // 解除锁定状态
        locker.set(false);
        try {
            // 通知
            locker.notify();
        } catch (Exception ignored) {
        }
    }
    }
}
  1. Monitorear cada mensaje del cliente para obtener canal a través selectionKeys, y a continuación, realiza una operación de entrada
try {
if (readSelector.select() == 0) {
    continue;
}

Set<SelectionKey> selectionKeys = readSelector.selectedKeys();
for (SelectionKey selectionKey : selectionKeys) {
    if (selectionKey.isValid()) {
        //IO处理代码,暂且忽略
    }
}
selectionKeys.clear();
} catch (IOException e) {
e.printStackTrace();
}

Nota: Estos son algunos fragmentos de código, no hay completamente juntos, y omite algunos de la clase de objeto llamada, llamada de método y operación de tecla, etc., del grupo de subprocesos. Sin embargo, el enfoque básico se ha mostrado, el resto del blog volver a llenar el hoyo.

Mira el código anterior, algún método NIO cognitiva es muy vaga. Los siguientes comentarios tras leer el selector de clase y clases SelectionKey fuente, para profundizar en la comprensión de la parte del método.

selector de clase

selector de NIO es las clases básicas, aquí hay algunos selector de método importante:

  • abierta Relacionados
    • open () Abre un selector
    • abstract boolean pública isOpen (); determinar si se debe abrir
public static Selector open() throws IOException {
    return SelectorProvider.provider().openSelector();
}
  • claves relacionados
    • Conjunto abstracto pública Llaves (); devuelven todos el conjunto de claves
    • Conjunto abstracto pública los selectedKeys (); conjunto tecla de retorno se ha seleccionado
  • Seleccione
    • Varios métodos son los siguientes rendimientos listos el número de canales, puede ser 0;
    • selectNow (), un método de no bloqueo;
    • SELECT (), devuelve sólo en tres casos, se selecciona un canal ;. Método llamada 2 wakeup; 3. interrupciones de rosca.
    • seleccionar (tiempo de espera), que seleccionar () una pluralidad de estado no bloqueado, es decir, tiempo de espera.
  • wakeup (), seleccione el método de elevación bloqueo bloqueo, volver inmediatamente
  • close (), cerrar el selector.

clase SelectionKey

Cualquier registrado en un selector de canales se utilizan para referirse a una objetos SelectionKey.

Colección operación

  • Operación-set: un conjunto de operaciones, algunas constantes int valor, que representan diversos tipos de operaciones; tecla de selección comprende un conjunto de dos operaciones, juego de interés, y conjunto listo-operación
public static final int OP_READ = 1 << 0;
public static final int OP_WRITE = 1 << 2;
public static final int OP_CONNECT = 1 << 3;
public static final int OP_ACCEPT = 1 << 4;
  • conjunto interés: interés Set; todos los canales de un conjunto de operaciones; puede ser actualizada por interestOps (int) Método

  • Set Ready-operación: operación Set Ready, de tal manera que el canal incluye sólo una operación listo para ser informado, con o actualiza por la operación subyacente; por ejemplo, cuando un canal está listo para leer, se añade la operación de lectura a la concentración actual listo.

Lista método

  • canal SelectableChannel abstracta pública (): Devuelve los canales asociados a esta tecla de selección, incluso si esta clave ha sido cancelada, siendo volverá ;.
  • Selector Selector abstracta pública (): Devuelve este selector para seleccionar la tecla asociada, incluso si esta clave ha sido cancelada, aún retornos;
  • abstract boolean pública isValid (): Esta clave es válida cuando la llave de detección se cancela, o el canal está cerrado, o el selector está cerrado, esto se traducirá en un (clave) AbstractSelector.removeKey tecla no válida, se pone a causa SelectionKey. inválida;
  • cancelar public abstract void (): esta tecla para cancelar la solicitud de registro A su regreso éxito, entonces la clave no es válida, la propiedad válidos se añade a la receta en cancelledKeys .cancel selector de operación clave es falsa, y ejecuta selector.cancel (. llave) (de próxima clave de combinación colección cancelledkey);
  • interesOps int abstractos públicos (): Este conjunto de teclas obtuvo interes;
  • interestOps públicas abstractos SelectionKey (PO int): esta tecla interst al valor especificado y esta voluntad ops ops channel.validOps Compruebe si este no soporta el canal actual, se producirá una excepción ;.
  • public int readyOps abstractos (): se preparan en este conjunto clave de las operaciones que ya está en su lugar sobre los acontecimientos actuales del canal ;.
  • pública final boolean isReadable (): se detecta Esta tecla "leer" la disposición evento es equivalente a:.! (readyOps () y OP_READ) = 0; no isWritable (), isConnectable (), isAcceptable ()
  • Objeto public final colocar (ob Object): objeto dado como un archivo adjunto en esta tecla, la pluralidad de fijación puede ser transferido en una clave de evento ops período de validez ;.
  • Objeto apego public final (): Obtiene el apego accesorio de un canal, y presentarla canal (o es SelectionKey) compartieron el ciclo de vida, pero los datos no es como la transmisión de datos toma archivo adjunto en la red.

Finalmente terminado, este blog sólo puede ser considerado como una breve introducción de NIO, algo que no se mencionan. método de canal y la memoria intermedia no es parte del análisis, el grupo de subprocesos no es parte plus, así como la salida de operar el conjunto, no hablaba. Siempre quiere terminar como mucho más detallado, pero el más vasto conocimiento más profundo, que sólo se puede renunciar a una parte del contenido, por lo que se convirtió así ahora. Si un plan detallado para abrir más de una escritura del blog será mejor.

Supongo que te gusta

Origin www.cnblogs.com/buptleida/p/12633675.html
Recomendado
Clasificación