2011-01-18 25 views
9

Nunca di el uso de Thread. He dormido mucho, hasta que descargué la última versión de Netbeans. Netbeans ahora te advierte que no uses Thread.Sleep. Así que investigué un poco sobre el tema y encontré personas que decían que solo necesitabas usar Thread.Sleep para depurar/probar y que si lo usabas en otro momento, tenías un código mal escrito.Cómo evitar el uso de Thread.Sleep

Así que mi pregunta es cómo puedo evitar el uso de Thread.Sleep en la siguiente situación.

He escrito una aplicación de servidor que se conecta con otra aplicación. El servidor tiene dos hilos:

  1. maneja los datos que llegan a través del socket y devuelve otra información o acknoledgements simplemente.

  2. Este es el hilo principal. Después de iniciar el zócalo, hágalo entrar en un ciclo indefinido. Dentro de este ciclo while, verifico para asegurarme de que el hilo del socket aún está activo y que el usuario no ha solicitado salir de la aplicación a través de la interfaz TrayIcon. Luego duermo y continúo este ciclo while.

Con esta aplicación, el TrayIcon es la única interfaz de usuario.

Aquí es el fragmento que estoy haciendo referencia:

// continues running as long as the exitth file is not present and 
// the tray icon is not in a safe to exit status. 

while(doNotExit()) 
{ 

    if (getPrimaryThread() == null || !getPrimaryThread().isAlive()) 
     resetsThreadAndSocket(); 

    try 
    { 
     // check to see if the socket threads are still active, if not create new ones. 
     if ((getPrimaryThread() == null || !getPrimaryThread().isAlive()))  
      createSocketThread(); 

     // check right before sleeping that the user does not want to exit. 
     if(getTrayIcon().isExiting()) 
      break; 

     // puts the main Thread to sleep for 3 seconds 
      Thread.sleep(3000); 
    } 
    catch(SQLException ex) 
    { 
     _log.error(ex.getMessage(), ex); 
     restartDatabase(); 
    } 
} 
+2

¿Por qué necesitas dormir aquí en primer lugar? – Elalfer

+0

Aquellos de nosotros que somos principiantes en el multihilo (incluyéndome a mí) nos preocupa quemar nuestros procesadores o causar problemas de vida. – Pete

+0

No soy el motivo por el que está ejecutando el Thread.sleep() aquí tampoco. ¿Está tratando de protegerse contra el acceso a un recurso compartido (alguna estructura de datos u objeto)? –

Respuesta

3

En lugar de su Thread.sleep (3000) Hacer:

getPrimaryThread().join(3000) 

Este esperará a que el hilo a la salida durante 3 segundos.

6

El método 'preferido' en la mayoría de los casos sería usar el ScheduledExecutorService integrado en JavaSE para realizar una tarea periódica, en lugar de volver a implementarlo usted mismo cada vez usando un ciclo while y Thread.Sleep().

No hay nada de malo en su ejemplo. El lenguaje ahora tiene un soporte mucho más robusto para hacer eso incorporado desde Java 5.

2

Debería considerar adjuntar un detector de eventos al icono de su bandeja en lugar de sondear su estado. De esta forma, no necesitará un hilo adicional solo para el monitoreo.

Si no puede hacer eso por alguna razón, aún puede eliminar el hilo adicional ya que la clase Timer puede hacerlo esperar.

1

Parece paranoico que alguna condición (¿tal vez una RuntimeException o un error?) Va a causar que su socket se acabe de morir. Idealmente, diseñaría su zócalo de socket de forma tal que se protegiera contra choques. En el siguiente ejemplo se crea un bucle que sólo se pueden romper como resultado de un error o una rosca de interrupción JVM:

public void run() { 
    while(!Thread.currentThread.isInterrupted()) { 
     try { 
      //you application logic 
     } catch (RuntimeException e) { 
      //log uncaught exception 
     } 
    } 
} 

Con el fin de apagar la aplicación, se uniría a un oyente a la TrayIcon que contenía una referencia a la SocketThread y podría detenerlo simplemente interrumpiéndolo.

socketThread.interrupt(); 

Dejaré averiguar cómo agregar un ActionListener a un TrayIcon depende de usted.

Cuestiones relacionadas