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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> метод join, как работает метод join? 
V
    Опции темы
Pawl
Дата 8.3.2011, 23:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Уважаемые господа,
В одной статье вычитал, что метод join(), вызванный на потоке t, "блокирует текущий поток до того времени пока поток t не умрет". Когда 2 потока понятно, а как работает этот метод если в приложении запущено 3 и более потоков? Если на одном из них вызвать join, как понять, какой из остальных будет заблокирован? В одной книге нашел пример и немного его переделал:
Код

class NewThread implements Runnable {
    String name; // имя потока
    Thread t;
    
    NewThread(String threadname) {
        name = threadname;
        t = new Thread(this, name);
        System.out.println("Новый поток: " + t);
        t.start();
    }
    
    public void run() {
        for (int i = 3; i > 0; i--) {
            System.out.println(name + ": " + i);
        }            
        System.out.println(name + " завершен.");
    }
}

Код

class DemoJoin {
    public static void main(String args[]) {
        try {
            NewThread ob1 = new NewThread("Первый");
            ob1.t.join();
            NewThread ob2 = new NewThread("Второй");
            ob2.t.join();
            NewThread ob3 = new NewThread("Третий");
            ob3.t.join();            
        } catch (InterruptedException e) {}
        System.out.println("Завершение главного потока.");
    }
}

вывод тут получается нормальный:
Новый поток: Thread[Первый,5,main]
Первый: 3
Первый: 2
Первый: 1
Первый завершен.
Новый поток: Thread[Второй,5,main]
Второй: 3
Второй: 2
Второй: 1
Второй завершен.
Новый поток: Thread[Третий,5,main]
Третий: 3
Третий: 2
Третий: 1
Третий завершен.
Завершение главного потока.

Но если класс DemoJoin сделать так:
Код

class DemoJoin {
    public static void main(String args[]) {
        try {
            NewThread ob1 = new NewThread("Первый");
            NewThread ob2 = new NewThread("Второй");
            NewThread ob3 = new NewThread("Третий");
            ob3.t.join();            
        } catch (InterruptedException e) {}
        System.out.println("Завершение главного потока.");
    }
}

получается, что поток ob3 завершается предпоследним, перед завершением главного потока. Потоки ob1 и ob2 не присоединяются к ob3 (не блокируются), а заканчиваются раньше него. Вот и прошу я объяснить мне тонкости работы с методом join!
Большое спасибо заранее!


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
jk1
Дата 9.3.2011, 04:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

Если на одном из них вызвать join, как понять, какой из остальных будет заблокирован?


Текущий будет заблокирован, из которого вызывали. Все же написано:

Цитата

метод join(), вызванный на потоке t, блокирует текущий поток до того времени пока поток t не умрет


Текуший поток будет заблокирован до завершения потока t. Все остальные потоки будут работать как и раньше, сколько бы их не было.

Цитата

Потоки ob1 и ob2 не присоединяются к ob3 (не блокируются), а заканчиваются раньше него.


Разница между двумя примерами в том, что в первом Вы сначала вызвали конструктор (запустили поток), потом дожались его завершения (join), создали следующий, дождались его и так далее. То есть в первом случае программа выполняется линейно и вообще непонятно, зачем там потоки. Во втором случае вы сначала запускаете 3 независимых потока, а потом дождаетесь завершения только одного из них. Остальные два при этом работают независимо.

Так что результат вполне предсказуем.


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


Опытный
**


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

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



Цитата

Текуший поток будет заблокирован до завершения потока t

Спасибо за ответ, но все же прошу уточнить. Если в приложении работают несколько потоков, они же все будут текущими? Так как же понять, какой из этих самых "текущих потоков" будет заблокирован?
Цитата

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

Вообще-то, по-моему, тут запускается 4 потока: основной, ob1, ob2 и ob3 причем именно в такой последовательности. Так вот, в примере дожидается завершения ob3 всегда только основной поток. Честно, непонятно, почему в данном случае "текущим" считается основной поток, а ob1 или ob2 - нет?


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
jk1
Дата 9.3.2011, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

Спасибо за ответ, но все же прошу уточнить. Если в приложении работают несколько потоков, они же все будут текущими?

Нет. Текуший поток - это поток выполняющий вызов join(). Кто этот вызов выполнил, тот и будет ждать окончания целевого потока. Посмотрите внимательно на Ваш класс NewThread. Он вызывает join()? Нет, значит и ждать он никого не будет. А вот starter thread, который исполняет main метод, делакт такой вызов, потому и ждет завершения.


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


Опытный
**


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

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



Спасибо огромное, помогли разобраться!
Закрываю тему.

Добавлено через 47 секунд
ВОПРОС РЕШЁН!


--------------------
В действительности всё совсем не так, как на самом деле
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.0620 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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