java multithreading netbeans sleep hint

NetBeans/Java/Nueva pista: Thread.sleep llamado en loop



multithreading hint (4)

Como otros han dicho, depende del uso. Un uso legítimo sería un programa que está diseñado para hacer algo cada 10 segundos (pero no es tan crítico que se requiera el tiempo exacto). Tenemos muchas de estas "aplicaciones de utilidad" que importan datos y otras tareas similares cada pocos minutos. Esta es una manera fácil de realizar estas tareas y, por lo general, estableceremos que el intervalo de sueño sea muy bajo y usemos un contador para que el programa se mantenga receptivo y pueda salir fácilmente.

int count = 0; while (true) { try { // Wait for 1 second. Thread.sleep(1000); } catch (InterruptedException ex) {} // Check to see if the program should exit due to other conditions. if (shouldExit()) break; // Is 10 seconds up yet? If not, just loop back around. count++; if (count < 10) continue; // 10 seconds is up. Reset the counter and do something important. count = 0; this.doSomething(); }

En NetBeans, hay una nueva pista que dice: Thread.sleep llamado en loop.

Pregunta 1: ¿Cómo / cuándo puede ser un problema dormir en un bucle?

Pregunta 2: Si es un problema, ¿qué debo hacer?

ACTUALIZACIÓN: Pregunta 3: Aquí hay un código. Dime en este caso si debería usar algo más en lugar de Thread.Sleep en un bucle. En resumen, esto es utilizado por un servidor que escucha las conexiones TCP del cliente. La suspensión se usa aquí en caso de que se alcance el número máximo de sesiones con los clientes. En esta situación, quiero que la aplicación espere hasta que esté disponible una sesión gratuita.

public class SessionManager { private static final int DEFAULT_PORT = 7500; private static final int SLEEP_TIME = 200; private final DatabaseManager database = new DatabaseManager(); private final ServerSocket serverSocket = new ServerSocket(DEFAULT_PORT); public SessionManager() throws IOException, SQLException { } public void listen() { while (true) if (Session.getSessionCount() < Session.getMaxSessionCount()) try { new Thread(new Session(database, serverSocket.accept())).start(); } catch (IOException ex) { ex.printStackTrace(); } else try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException ex) { ex.printStackTrace(); } } public static void main(String[] args) throws IOException, SQLException { new SessionManager().listen(); } }


Creo que encuentro un uso completamente legítimo del método sleep() en loop.

Tenemos una conexión de ida entre el servidor y el cliente. Entonces, cuando el cliente desea lograr una comunicación asíncrona con el servidor, envía un mensaje al servidor y luego periódicamente busca alguna respuesta del servidor. Debe haber algún intervalo de tiempo de espera.

Response resp = null; for (int i = 0; i < POLL_REPEAT && resp == null; i++) { try { Thread.sleep(POLL_INTERVAL); } catch (InterruptedException ie) { } resp = server.getResponse(workflowId); }

POLL_REPEAT * POLL_INTERVAL ~ intervalo de tiempo de POLL_INTERVAL


Llamar a dormir en un bucle generalmente conduce a un rendimiento pobre. Por ejemplo:

while (true) { if (stream.available() > 0) { // read input } sleep(MILLISECONDS); }

Si MILLISECONDS es demasiado grande, este código tardará mucho tiempo en darse cuenta de que la entrada está disponible.

Si MILLISECONDS es demasiado pequeño, entonces este código desperdiciará una gran cantidad de recursos del sistema para verificar la entrada que aún no ha llegado.

Otros usos del sleep en un ciclo son generalmente cuestionables también. Usualmente hay una mejor manera.

Si es un problema, ¿qué debería hacer en su lugar?

Publique el código y tal vez podamos darle una respuesta sensata.

EDITAR

OMI, una mejor manera de resolver el problema es usar un ThreadPoolExecutor .

Algo como esto:

public void listen() { BlockingQueue queue = new SynchronousQueue(); ThreadPoolExecutor executor = new ThreadPoolExecutor( 1, Session.getMaxSessionCount(), 100, TimeUnit.SECONDS, queue); while (true) { try { queue.submit(new Session(database, serverSocket.accept())); } catch (IOException ex) { ex.printStackTrace(); } } }

Esto configura al ejecutor para que coincida con la forma en que su código funciona actualmente. Hay otras maneras en que podrías hacerlo; ver el enlace javadoc arriba.


¿Cómo / cuándo puede ser un problema dormir en un bucle?
Las personas a veces lo emplean en lugar de los métodos de sincronización adecuados (como wait / notify).

Si es un problema, ¿qué debería hacer en su lugar?
Depende de lo que estás haciendo. Aunque es difícil para mí imaginar una situación en la que hacer esto sea el mejor enfoque, creo que eso también es posible.

Puede consultar el tutorial de simultaneidad de Sun sobre este tema.