Java NIO defecto inherente en la lectura de un zócalo y escrito a otro?

Ben:

Yo trabajo en un concepto de servidor mínima básica que fluye datos de un puerto a otro destino mediante canales NIO y hembra.

Las cosas funcionan muy bien a toda velocidad, conexiones rápidas, etc cosas fallan terriblemente y consumen una gran cantidad de CPU cuando un lado es más rápido que el otro. Cosas de trabajo, sólo el trabajo de manera muy ineficiente.

Ejemplo:

Iterator keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
    SelectionKey key = (SelectionKey) keys.next();
    keys.remove();
    try {
        if (!key.isValid()) continue;
        if (key.isReadable()) read(key);
    }
    catch (Exception e) {
        e.printStackTrace();
        key.cancel();
    }
}

La llamada de lectura que ocurre cada vez que el conector tiene datos que pueden ser leídos. Pero lo que si se puede escribir la parte de este conector no se puede escribir en el lado del cliente, porque tiene una alta latencia o simplemente no está leyendo los datos de forma rápida? Terminamos bucle a un ritmo loco no hacer nada hasta que un poco más de amortiguación libera grabables arriba:

public void read(SelectionKey key) throws IOException {
    ByteBuffer b = (ByteBuffer) buffers.get(readable); //prior buffer that may or may not have been fully used from the prior write attempt
    int bytes_read = readable.read(b);
    b.flip();
    if (bytes_read > 0 || b.position() > 0) writeable.write(b);
    b.compact();
}

Así que decimos que podemos leer por el orificio de un gigabit, pero el receptor sólo es una lectura de nuestra toma de permisos de escritura en 100kilobit .... podríamos bucle de un millón de veces entre cada pedazo de datos se puede escribir sobre el cliente, ya que sólo no están consumiendo los datos de los buffers de los conectores tan rápido como queremos.

Si lo hiciera esto con un hilo, no habría ningún problema, ya que estaría bloqueando en la llamada de escritura. Pero con NIO, lo que se supone que debes hacer para que se salte las notificaciones leer?

Ben:

Me di cuenta de esto. Todavía no he encontrado documentos señalarme en esto, pero después de considerar las cosas más me daba cuenta que esto es lo que el escenario es para OP_WRITEABLE.

Así que cuando los rendimientos grabables que aceptaba 0 bytes, que cancelar el registro del OP_READ en el canal de lectura y registro para OP_WRITEABLE en el canal de escritura. Una vez se me notifica que su grabable, me cambiaré de vuelta los canales de lectura / escritura, incluyendo lo que están registrados para dejar caer el OP_WRITEABLE ahora.

Por eso, cuando una escritura no se puede hacer, de-registro de la lectura que está provocando que pruebe y escribir en él, y registrarse para una notificación de escritura en su lugar. Una vez que conseguir eso, registros de espalda de intercambio.

Las cosas funcionan bien ahora.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=217823&siteId=1
Recomendado
Clasificación