usando sleep () para un solo hilo

Soy bastante nuevo en Java y estoy empezando a usar diferentes hilos para usar wait() o sleep() en una parte de mi código y hacer que los otros sigan ejecutándose.

Para este proyecto, estoy usando JFrame con las javax.swing.* Y java.awt.* . Lo que estoy tratando de hacer es tener uno de los hilos (en mi código es el hilo principal, de inicio) permitir al jugador elegir un espacio en el tablero de tres en raya, y cuando lo hagan, cambiará los icons, y entonces la IA esperará por 1 segundo antes de reproducir desde el segundo hilo que creé.

Desafortunadamente, cada vez que llamo ait.sleep(1000) ( ait es el nombre de mi hilo) ambos hilos esperan 1 segundo antes de finalizar su ejecución. ¿Alguien puede decirme por qué dormir un hilo detiene toda mi ejecución?

    ¿Alguien puede decirme por qué dormir un hilo detiene mi ejecución completa?

    para explicar mejor su GUI Swing se crea en su propio hilo especial separado de aquel en el que se ejecutarán main() y otro código, esto se hace creando sus componentes Swing en el bloque SwingUtilities.invokeXXX (incluso si no lo ha hecho, La GUI se ejecutará en un único subproceso llamado subproceso inicial ). Ahora, si simplemente llama a sleep mientras está en el Event Dispatch Thread (o para el caso en el mismo Thread ), esperará a que Thread.sleep la llamada a Thread.sleep . Ahora, debido a que todos los eventos Swing se procesan en EDT, pausamos su ejecución llamando a sleep(..) deteniendo así los eventos UI para que no se procesen y, por lo tanto, la GUI se congela (hasta que vuelve el sleep(..) ).

    No debe usar Thread.sleep(..) en Event Dispatch Thread (o cualquier Thread donde sleep interrumpirá el locking de ejecución no deseado), ya que esto hará que la IU parezca congelada.

    Aquí hay un buen ejemplo que demuestra exactamente, este comportamiento no deseado causado por la invocación de Thread.sleep(..) en EDT de GUI.

    Más bien uso:

    • Swing Timer por ejemplo:

       int delay=1000;// wait for second Timer timer = new Timer(delay, new AbstractAction() { @Override public void actionPerformed(ActionEvent ae) { //action that you want performed } }); //timer.setRepeats(false);//the timer should only go off once timer.start(); 
    • Trabajador de Swing

    o si no se crean / modifican componentes Swing:

    • TimerTask

    • Subproceso , entonces Thread.sleep(int milis) (pero esa última opción en cualquier caso IMO)

    ACTUALIZAR

    Swing Timer / SwingWorker solo se agregó en Java 1.6, sin embargo, TimerTask y Thread han existido durante mucho más tiempo sinusoles Java 1.3 y JDK 1, por lo que incluso podría usar cualquiera de los 2 métodos anteriores y ajustar las llamadas que crean / manipulan componentes Swing en SwingUtilities/EventQueue#invokeXX block; esa es la forma en que solían hacerse las cosas: P

    Thread.sleep es un método estático. Las invocaciones a través de la referencia de cualquier Thread dado son simplemente una forma de conveniencia.

    Como resultado, cualquier invocación de sleep realmente llama a sleep en el Thread actual, que sospecho que es el hilo del evento en su caso. Dormir / bloquear en el hilo del evento dará la apariencia de estar encerrado.

    Si quieres que el hilo ait duerma, codifica ese hilo para dormir. Los diseños en los que un hilo “alcanza” a otro y lo empuja a un nivel bajo están fundamentalmente rotos. Usted escribe el código para cada hilo, así que escríbalo para hacer lo que quiera que haga en primer lugar, por lo que no tendrá necesidad de alcanzarlo desde afuera.

    ¿Qué tiene más sentido, que la persona en la cocina sepa cómo preparar el desayuno o la persona que está en el dormitorio para gritar y dirigirlos a cada paso del desayuno? Claro, puedes decirles que preparen el desayuno. Pero definitivamente no dirige cada paso a un nivel bajo.

    Thread.sleep es un método estático que hace que el hilo que se está ejecutando actualmente duerma durante el tiempo especificado. La syntax de Java le permite llamar a un método estático a través de una variable, pero el comstackdor simplemente usa el tipo de tiempo de comstackción de esa variable para determinar qué método llamar, es decir,

     Thread ait = null; ait.sleep(1000); // calls Thread.sleep(1000), causing current thread to sleep. // In particular, does *not* NPE 

    También mencionó wait() : aunque este es un método de instancia en lugar de estático, sigue causando que el hilo actual haga la espera ( ait.wait(1000) haría que el hilo actual espere hasta 1 segundo o hasta que otro hilo llama ait.notifyAll() ).

    Hay un Thread.suspend() y su contrapartida resume() que se introdujeron en los primeros días de Java para permitir que un hilo controle a otro, pero fueron desaprobados poco después ya que son intrínsecamente propensos a interlockings. El patrón recomendado si quiere que un hilo “controle” otro es hacerlo cooperativamente, es decir, tener algún tipo de indicador compartido que el hilo A establece y lee el hilo B, y que B se envíe a dormir de acuerdo con el indicador:

     volatile boolean threadBShouldRun = true; // Thread B while(true) { if(threadBShouldRun) { // do some stuff } else { Thread.sleep(1000); } } // Thread A if(someCondition) { threadBShouldRun = false; } 

    pero generalmente es más fácil y menos propenso a errores hacer uso de las instalaciones que existen en el paquete java.util.concurrent . Hacer múltiples hilos a la derecha es mucho más difícil de lo que parece en la superficie.