NetBeans / Java / Новая подсказка: Thread.sleep вызывается в цикле - PullRequest
47 голосов
/ 21 августа 2010

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

Ответы [ 4 ]

22 голосов
/ 21 августа 2010

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

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

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

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

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

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

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

РЕДАКТИРОВАТЬ

ИМО, лучший способ решить эту проблему - использовать 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 выше.

3 голосов
/ 15 июля 2011

Как уже говорили другие, это зависит от использования.Законное использование - это программа, предназначенная для выполнения каких-либо действий каждые 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();
}
2 голосов
/ 17 июля 2012

Я думаю, что наткнулся на одно вполне законное использование метода 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

2 голосов
/ 21 августа 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...