NetBeans / Java / New hint: Thread.sueño llamado en bucle


En NetBeans, hay una nueva pista que dice: Hilo.sueño llamado en bucle.

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 estar usando algo más en lugar de Hilo.Duerme en bucle. En resumen, esto es utilizado por un servidor que escucha las conexiones TCP del cliente. Se utiliza el sueño 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 una sesión gratuita esté disponible.

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();
}
}
Author: Mr_and_Mrs_D, 2010-08-21

4 answers

Llamar al sueño en un bucle normalmente conduce a un rendimiento deficiente. Por ejemplo:

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

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

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

Otros usos de sleep en un bucle son típicamente cuestionables también. Normalmente 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

IMO, una mejor manera de resolver el problema es utilizar 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 el ejecutor para que coincida con la forma en que su código funciona actualmente. Hay un número de otras maneras en que podría hacerlo; vea el enlace de javadoc arriba.

 20
Author: Stephen C,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-21 07:18:35

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 necesite 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 el intervalo de sueño para que sea muy bajo y usaremos un contador para que el programa permanezca 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();
}
 3
Author: java nut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-14 20:55:17

¿Cómo / cuándo puede ser un problema dormir en bucle?
La gente a veces lo emplea en lugar de métodos de sincronización adecuados (como esperar/notificar).

Si es un problema, ¿qué debo 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 es el mejor enfoque, supongo que eso también es posible.

Puede consultar El tutorial de concurrencia de Sun sobre este tema.

 2
Author: Nikita Rybak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-21 00:43:14

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

Tenemos una conexión unidireccional 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 sondea periódicamente para obtener alguna respuesta del servidor. Tiene que 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 espera

 1
Author: Ondrej Bozek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-17 14:47:48