Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Приостановка и возобновление потоков 
:(
    Опции темы
zss
Дата 13.7.2005, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: нет
Всего: 2



поддержка Runnable подразумевает метод run()

мне нужна возможность приостановки и запуска потока.

единственное решение - зациклить код и использовать флаг

Код

public void run(){
    while (true){
        if (flag){
            //что-то делаем
            thread.sleep(...);
        }
    }
}


но тогда поток (если этого ненужно) постоянно гоняется в цикле (трата процессорного времени)

Можно ли приостановить поток и перезапустить его ?
PM MAIL ICQ   Вверх
djGri
Дата 13.7.2005, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 77
Регистрация: 21.2.2005

Репутация: 1
Всего: 3



функция wait() - усыпляет

используется в блоке
Код

try {
wait();
}catch (InterruptedException e)


функция notify() - будит

Если есть еще треды, используй yield() , чтобы усыпить, notify() - будить
PM MAIL   Вверх
Erast
Дата 14.7.2005, 01:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 14.7.2005

Репутация: нет
Всего: нет



а лучше все-таки

Код

try 
{    
  sleep();    
}
catch (InterruptedException e)

sleep отдает процессорное время, а wait нет
PM MAIL   Вверх
Domestic Cat
Дата 14.7.2005, 04:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172



А еще лучше - исходный вариант
Код

public void run(){
    while (true){
        if (flag){
            //что-то делаем
        }
    }
}



--------------------

PM   Вверх
Zandr
Дата 14.7.2005, 06:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 433
Регистрация: 16.7.2004
Где: Новосибирск

Репутация: 9
Всего: 13



Да уж тогда лучше:
Код

public void run(){    
    while (true){    
        if (flag){    
            //что-то делаем    
        } else {
            yield(); // "пропускаем ход"
        }
    }    
}

Без yield() в данном случае на некоторых операционках может получиться лажа, особенно если этот тред имеет приоритет больше чем у других тредов (немного неточно сформулировал). Все это очень хорошо описано в туторе по тредам. Откуда вообще такие вопросы берутся на форуме? smile

Дополнение: yield() лучше вообще из else вынести, чтобы проходил на каждом выполнении цикла.

Это сообщение отредактировал(а) Zandr - 14.7.2005, 06:03
PM MAIL   Вверх
Domestic Cat
Дата 14.7.2005, 06:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172



Цитата(Zandr @ 13.7.2005, 21:02)
Без yield() в данном случае на некоторых операционках может получиться лажа, особенно если этот тред имеет приоритет больше чем у других тредов (немного неточно сформулировал). Все это очень хорошо описано в туторе по тредам. Откуда вообще такие вопросы берутся на форуме? smile

В твоем варианте будет нехило кушацца процессор тк тред спать не будет а просто будет гоняться в цикле. yield ничего особенного не делает, это команда дать другим потокам время на выполнение, т.е. перепланировать распределение времени между процессами.


--------------------

PM   Вверх
Zandr
Дата 14.7.2005, 08:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 433
Регистрация: 16.7.2004
Где: Новосибирск

Репутация: 9
Всего: 13



Ну так вот именно smile Проверить running мы или нет, если да, то выполнить что-то-там, потом дать другим выполнить что-то там.
А варианте выше проц тоже будет кушаться. На постоянную проверку флага. Которая так же будет гоняться в цикле. Или компилятор сумничает и проведет какую-то оптимизацию?
PM MAIL   Вверх
Domestic Cat
Дата 14.7.2005, 08:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172



Цитата(Zandr @ 13.7.2005, 23:16)
Ну так вот именно smile Проверить running мы или нет, если да, то выполнить что-то-там, потом дать другим выполнить что-то там.
А варианте выше проц тоже будет кушаться.

Если поставить sleep то не будет. Я к тому, что yield sleepа не заменит.


--------------------

PM   Вверх
Metal_Heart
Дата 14.7.2005, 08:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а почему бы и нет?
**


Профиль
Группа: Участник
Сообщений: 728
Регистрация: 31.3.2005
Где: Москва

Репутация: 4
Всего: 12



Domestic Cat и Zandr

Вы уж меня извините, но чем, В ПРИНЦИПЕ, отличны ваши коды?



--------------------
 не стыдно учиться, а стыдно не учиться 
PM ICQ   Вверх
Zandr
Дата 14.7.2005, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 433
Регистрация: 16.7.2004
Где: Новосибирск

Репутация: 9
Всего: 13



А вообще лучше как раз разобраться с wait-notify.
Код

public class Thr implements Runnable {
    private boolean stopped;
    private boolean paused;

    synchronized public void pause() {
        paused = true;
        notify();
    }
    
    synchronized public void resume() {
        paused = false;
        notify();
    }
    
    synchronized public void stop() {
        stopped = true;
        notify();
    }

    public void run() {
        while (!stopped) {
            if (!paused) {
                doNextStep();
            } else {
                synchronized (this) {
                    try {
                        wait();
                    } catch (InterruptedException e) {}
                }
            }
        }
    }
    
    private void doNextStep() {
        // some work, game scene repaint for example
    }
}

Если синхронизация нужна еще для каких-то целей, можно сделать объект-пустышку и делать synchronized( lockObject) {...}

Это сообщение отредактировал(а) Zandr - 14.7.2005, 08:46
PM MAIL   Вверх
zss
Дата 14.7.2005, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: нет
Всего: 2



Domestic Cat, а почему лучше мой способ ? ведь процессорное время кушается без нужды.
и почему плохо yield() - впольне логично отдать процессорное время при ненадобности.

поставить sleep я не могу - ведь мне нужно преостановить поток из другого потока на неопределенное время.

Тоесть пока я не захочу - мой поток спит (неограниченное время). Как только я захотел - он просыпается - можно ли так сделать.


З.Ы. Более того - корректное завершение потока в любой ОС - это дать завершиться потоковой функции. Но в данном случае она никогда не завершиться, ведь
Код

while(true){
}


может тогда по лучше при каждой надобности просто создавать новый объект Thread и запускать его, а когда он не нужен - убивать его - тогда будет правильнее(интервалы между созданиями потоков достаточно большие). Или я неправ?
PM MAIL ICQ   Вверх
Domestic Cat
Дата 14.7.2005, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172



В Java нет средств остановить или продолжить выполнение потока. Но это можно обойти несколькими способами.
1. Создавать тред каждый раз. Проблема в том, что его нельзя просто остановить, он сам должен узнать что должен остановиться. Плюс нужно передавать данные из треда в новый тред. Все это ест ресурсы.
2. Использовать javax.swing.Timer. Там есть нужные методы
3. Использовать wait/notify.
4. Этот вариант
Код

while (true){
        if (flag){
            //что-то делаем
        }
    }

Если все так и оставить, то тред будет гонять холостой бесконечный цикл при флаге=фалс. Потому
Код

while (true){
        if (flag){
            //что-то делаем
        }
        else sleep(100);
    }

Главное тут - спать немного, нагрузка на проц намного уменьшится.
Насчет yield - это сигнал планировщику перепланировать временные срезы тредов. Это не сигнал остановить тред.



--------------------

PM   Вверх
NotGonnaGetUs
Дата 14.7.2005, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 92
Регистрация: 25.2.2005
Где: Москва

Репутация: 4
Всего: 12



плюсек за вариант Зандра.
если делать через sleep, поток всё равно будет кушать ресурсы, через wait/notify - не будет совсем.
PM MAIL   Вверх
Metal_Heart
Дата 14.7.2005, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


а почему бы и нет?
**


Профиль
Группа: Участник
Сообщений: 728
Регистрация: 31.3.2005
Где: Москва

Репутация: 4
Всего: 12



Спасибо, Domestic Cat, а что делать на случай аварийного зацикливания потока?


--------------------
 не стыдно учиться, а стыдно не учиться 
PM ICQ   Вверх
zss
Дата 15.7.2005, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: нет
Всего: 2



Zandr, спасибо - помогло
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0542 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.