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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> CountDownLatch и остановка потока 
V
    Опции темы
xbarmaglot
Дата 17.2.2013, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Есть поток, который должен засыпать на длительное время, но который нужно быстро остановить по требованию.
Решил использовать CountDownLatch.

Код

        private final CountDownLatch    m_sync = new CountDownLatch(1);

    public final boolean stopThread()
    {
        try
        {
            m_sync.countDown();
            super.join();        
            return true;
        }
        catch (Exception ex)
        {
            Log.e(this.getClass().getName(), ex.getMessage());
            return false;
        }
    }
    @Override
    public void run()    
    {            
        try
        {
            do
            {
                              ...
            }
            while (!m_sync.await(900, TimeUnit.SECONDS)); // 15 мин.
        }
        catch (Exception ex)
        {
            Log.e(this.getClass().getName(), ex.getMessage());
        }
    }    



Это нормальное решение или можно как еще ?
PM MAIL   Вверх
jk1
Дата 17.2.2013, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

Это нормальное решение


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

Код

public class Task implements Runnable {

    @Override
    public void run() {
        try {
            do {
                System.out.println("Doing some work");
                Thread.sleep(1000);
            } while (true);
        } catch (InterruptedException e) {
            System.out.println("Stopping thread");
        }
    }


    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Task());
        thread.start();
        Thread.sleep(5500);
        thread.interrupt();
    }
}


А вообще подобные вещи принято делать на таймерах, чтобы избежать возможных проблем при ручном разруливании взаимодействия потоков:

Код

import java.util.Timer;
import java.util.TimerTask;

public class Task extends TimerTask {

    @Override
    public void run() {
        System.out.println("Doing some work");
    }

    public static void main(String[] args) throws InterruptedException {
        Timer timer = new Timer();
        timer.schedule(new Task(), 1000, 1000);
        Thread.sleep(5500);
        timer.cancel();
    }
}



--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
xbarmaglot
Дата 17.2.2013, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(jk1 @  17.2.2013,  21:23 Найти цитируемый пост)
Нет. Если хочется сделать на голых потоках, то лучше пользоваться стандартными механизмами прерывания работы потока:

а чем мой способ плох ? Какие причины проблемм ?

Добавлено через 1 минуту и 36 секунд
Ведь я корректно завершаю поток...

Добавлено через 2 минуты и 25 секунд
Да и после thread.interrupt() нужен ли join() ?
PM MAIL   Вверх
jk1
Дата 17.2.2013, 22:58 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

а чем мой способ плох ? Какие причины проблемм ?


1. Тем, что использует нестандартный подход без необходимости. Совершенно типовая задача решается нестандартным способом.
2. Тем, что использует CountDownLatch не по назначению. Образно выражаясь, Вы копаете яму молотком. Теоретически это возможно, но непонятно зачем - проще взять лопату.
3. Тем, что это просто велосипед, в котором Вашим коллегам придется потом разбираться. Для периодических задач принято использовать таймеры или пулы потоков с функциональностью таймеров. Кстати все они в Java оборудованы возможностью прерывания. Зачем писать свое когда уже есть готовое?

Цитата

Да и после thread.interrupt() нужен ли join() ? 

Нет. Он и в исходном варианте не нужен. Зачем тормозить без причины вызывающий поток?


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
xbarmaglot
Дата 18.2.2013, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



c join понятно.
А вот поток у меня засыпает
Код

            do {
                System.out.println("Doing some work");
                Thread.sleep(900 * 1000);
            } while (true);


но нифига не просыпается.
То есть я не вижу периодических записей "Doing some work"
В чем может быть проблема ?
PM MAIL   Вверх
korian
Дата 18.2.2013, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(xbarmaglot @  18.2.2013,  08:26 Найти цитируемый пост)
но нифига не просыпается.
То есть я не вижу периодических записей "Doing some work"

из привиденного куска кода - так не бывает. Поток запущен?
PM   Вверх
xbarmaglot
Дата 19.2.2013, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



понятно

Есть еще несколько вопросов:
1. Как усыпить поток до ожидания прерывания ? То есть нужно в отдельном потоке запустить 
потоковый объект и ждать завершения потока. А если он останавливается, то в блоке finally остановить поток.
Просто Thread.sleep(0xFFFFFFFF) как-то кривовато smile
2. Если поток не запущен, то к чему приведет внешний вызов interrupt ? Ведь блок try/catch внутри потока.
Будет ли исключение брошено ? Если да, то уго нужно ловить извне ?
3. Если потоковый объект запущен, то будет ли он приостановлен, если сам поток засыпает на ожидании прерывания ?
PM MAIL   Вверх
jk1
Дата 19.2.2013, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

1. Как усыпить поток до ожидания прерывания ? То есть нужно в отдельном потоке запустить 
потоковый объект и ждать завершения потока. А если он останавливается, то в блоке finally остановить поток.
Просто Thread.sleep(0xFFFFFFFF) как-то кривовато 


А зачем нужен поток который ждет, пока его не прервут?

Цитата

2. Если поток не запущен, то к чему приведет внешний вызов interrupt ? Ведь блок try/catch внутри потока.


Вызывающий код получит IllegalThreadStateException

Цитата

3. Если потоковый объект запущен, то будет ли он приостановлен, если сам поток засыпает на ожидании прерывания ? 


Если поток ушел в sleep, то, очевидно, он не выполняется. Или под "приостановкой" Вы понимаете что-то другое?


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
xbarmaglot
Дата 19.2.2013, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(jk1 @  19.2.2013,  17:30 Найти цитируемый пост)
А зачем нужен поток который ждет, пока его не прервут?

чтоб можно было использовать блок try/finally

Цитата(jk1 @  19.2.2013,  17:30 Найти цитируемый пост)
Вызывающий код получит IllegalThreadStateException

понятно

Цитата(jk1 @  19.2.2013,  17:30 Найти цитируемый пост)
Если поток ушел в sleep, то, очевидно, он не выполняется. Или под "приостановкой" Вы понимаете что-то другое? 

поток создает объект, который работает. А сам засыпает. Так вот будет ли объект тоже спать ?
PM MAIL   Вверх
xbarmaglot
Дата 21.2.2013, 19:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



еще вопрос - можно ли после interrupt снова запускать поток ? Или его нужно пересоздавать ?
PM MAIL   Вверх
jk1
Дата 24.2.2013, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



interrupt не завершает работу потока, он просто выставляет флаг. Поток, прочитав этот флаг, может сам завершить свою работу (вернуть управление из метода run), если захочет. После завершения работы потока повторный его запуск уже невозможен.


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

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

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


 




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


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

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