2010-02-12 29 views
7

Estoy trabajando en un MUD en Java. Leo la entrada del jugador cada tic, pero estoy usando Scanner que usa operaciones de bloqueo. Quiero tener una entrada sin bloqueo.Consola de teclado concurrente/no bloqueada entrada

He visto el paquete nio que tiene una clase Selector, pero no estoy seguro de cómo usarlo con respecto a System.in. Me imagino que definitivamente lo necesitaré una vez que ejecute un servidor, pero por ahora todo está fuera de línea.

He intentado extender la clase principal desde Applet y anulando keyDown, pero eso solo significaba que la entrada ya no se aceptaba después de la primera. Claro, ya no estaba bloqueando nada, pero no había más información. keyDown nunca más me llamaron, supongo.

¿Quizás los hilos se pueden interrumpir incluso cuando están ejecutando operaciones de bloqueo?

Gracias por cualquier idea sobre este problema.

+0

enchufes no-bloqueo (redes) no se realiza de la misma forma que no bloqueante IO, al menos no en la mayoría de entornos. – Textmode

Respuesta

2

No se puede hacer eso con la consola del sistema porque por ahora no se puede hacer de una manera multiplataforma.

Puede usar la ventana swing como consola o buscar un enfoque basado en JNI, pero podría no funcionar en algunas plataformas.

Puede usar JCurses. Podría funcionar, está basado en JNI y es compatible con Windows y Linux.

+0

JCurses se basa en 'maldiciones' UNIX por lo que definitivamente funcionará. – H2ONaCl

+0

A partir del 2014-05-23, el enlace de 'explicación' está muerto (ahora los enlaces a la página de estacionamiento de dominio). – daveloyall

+0

@daveloyall Lo eliminé. Gracias. – aalku

0

keyDown() es deprecated así que te sugiero utilizar processKeyEvent y una keyListener lugar.

¿Quizás los hilos se pueden interrumpir incluso cuando están ejecutando operaciones de bloqueo?

Sí, si tiene una referencia al objeto de subproceso que desea interrumpir, simplemente puede llamar al método interrupt() en esa instancia. Y en el método de ejecución del subproceso, puede manejar la excepción interrumpida. Sin embargo, esto parece un poco hack-ish. No veo cómo esto es más útil que usar un KeyListener simple.

+0

Thread.interrupt() solo establece el indicador de interrupción y reactiva el hilo si está activado o bloqueado. No interrumpe el archivo de bloqueo regular IO de la lectura de socket. Tampoco interrumpirá un cálculo pesado o un bloqueo de giro: su código debe verificar y obedecer el indicador de "interrupción" para poder ser interrumpido. – ddimitrov

-1

Tuve que resolver un problema similar con el bloqueo de escritura/lectura de http. En ese caso particular, utilicé buffer local y Threads.

La idea es simple, un hilo leído de stdin y contenido en buffer. Segundo haz lo mismo con la escritura.

Y luego utiliza consultas sin bloqueo en su búfer.

Código de ejemplo:

class NonBlockingReader implements Runnable{ 
    Reader in; 
    List buffer; 
    public void run(){ 
    String line=null; 
    while((line=in.readLine())!=null){ 
     storeLine(line); 
    } 
    } 
    private synchronized storeLine(String line){ 
    buffer.add(line); 
    } 
    public synchronized String getLine(){ 
    if(list.size()>0) 
     return list.removeFirst(); 
    return null; 
    } 
} 

// .. same for writer, then you jast pass stdin and stdout ... 
+0

el flujo System.in que es el equivalente stdin de Java está almacenado en el búfer, por lo que la aplicación no ve los caracteres hasta que el usuario presione enter. – ddimitrov

Cuestiones relacionadas