Подтвердить что ты не робот

NetBeans/Java/New hint: Thread.sleep, вызываемый в цикле

В NetBeans есть новый намек, в котором говорится: Thread.sleep, вызываемый в цикле.

Вопрос 1: Как/когда это может быть проблемой для сна в цикле?

Вопрос 2: Если это проблема, что мне делать вместо этого?

ОБНОВЛЕНИЕ: Вопрос 3: Вот какой код. Скажите мне в этом случае, если я должен использовать что-то другое вместо Thread.Sleep в цикле. Короче говоря, это используется сервером, который слушает клиентские TCP-соединения. Сон используется здесь, если достигается максимальное количество сеансов с клиентами. В этой ситуации я хочу, чтобы приложение подождало, пока свободный сеанс станет доступным.

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();
}
}
4b9b3361

Ответ 1

Вызов сна в цикле обычно приводит к низкой производительности. Например:

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

Если MILLISECONDS слишком велико, тогда этот код займет много времени, чтобы понять, что вход доступен.

Если MILLISECONDS слишком мал, то этот код будет тратить много системных ресурсов на вход, который еще не прибыл.

Другие виды использования sleep в цикле обычно также сомнительны. Как правило, лучший способ.

Если это проблема, что мне делать вместо этого?

Отправьте код и, возможно, мы сможем дать вам разумный ответ.

ИЗМЕНИТЬ

IMO, лучший способ решить проблему - использовать ThreadPoolExecutor.

Что-то вроде этого:

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();
        }
    }
}

Это настраивает исполнителя так, как работает ваш код. Существует множество других способов сделать это; см. ссылку javadoc выше.

Ответ 2

Как говорили другие, это зависит от использования. Допустимое использование - это программа, предназначенная для выполнения чего-то каждые 10 секунд (но не настолько важна, что требуется точное время). У нас есть много этих "служебных приложений", которые каждые несколько минут импортируют данные и другие подобные задачи. Это простой способ выполнить эти задачи, и мы обычно устанавливаем интервал ожидания очень низким и используем счетчик, чтобы программа оставалась отзывчивой и могла легко выйти.

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

Как/когда может быть проблемой спать в цикле?
Иногда люди используют его вместо правильных методов синхронизации (например, wait/notify).

Если это проблема, что я должен делать вместо этого?
Зависит от того, что вы делаете. Хотя для меня достаточно представить себе ситуацию, когда это лучший подход, я думаю, это тоже возможно.

Вы можете проверить Sun concurrency учебник по этому вопросу.

Ответ 4

Я думаю, что я сталкиваюсь с одним полностью законным использованием метода sleep() в цикле.

У нас есть односторонняя связь между сервером и клиентом. Поэтому, когда клиент хочет достичь асинхронной связи с сервером, он отправляет сообщение серверу, а не периодически опросы на какой-либо ответ от сервера. Должен быть некоторый интервал времени ожидания.

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 ~ Интервал TIMEOUT

Ответ 5

Это не лучшее решение, но вы можете уменьшить количество миллисекунд, например Thread.sleep(1);