public static void main(String[] args) {
for (Thread th : threads){
th.start();
}
((Task4)threads.get(3)).showWarning();
}
public static class Task4 extends Thread implements Message {
@Override
public void run() {
while (!isInterrupted()) {
}
}
@Override
public void showWarning() {
this.interrupt();
}
}
данный код рабочий. До него вместо iterrupted() и iterrupt() было isAlive(), не принималось, почему? - это первое.
второе : ((Task4)threads.get(3)).showWarning(); ну ни как мне не дается к пониманию это выражение, я его содрал. По другому метод showWarning() не вызывается, если его сделать статическим то ругается на оператор this. ((Task4)threads.get(3)).showWarning() - тут получается объект сужается до типа (Task4) что бы использовать его методы? Почему нельзя вызвать Task4.showWarning(), или создав объект Task4 task4 = new Task4(); task4.showWarning() ? На этом застрял на долго, списал но так и не понял почему не получается моими методами.Александр
20 уровень
Есть некоторые вопросы по методу в 4 нити, объясните плз популярно.
Решен
Комментарии (11)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
hidden #598481
28 декабря 2018, 11:57решение
Метод isAlive() проверяет жив ли этот поток. Выполнять эту проверку внутри этого потока бессмысленно, т.к. если ты внутри этого потока, значит он еще выполняется, и никакой interrupt() его не прервет. Проверим:
В консоли:
Как видишь, поток продолжил свой бесконечный цикл, несмотря на то, что мы установили ему флаг состояния прерванности.
Именно поэтому нужно проверять на isInterrupted().
Другими словами, isAlive() нужен, чтобы находясь снаружи потока (в главном потоке или в другом потоке) проверить, выполняется ли в настоящий момент целевой поток. isInterrupted() наоборот нужен, чтобы проверить, находясь внутри потока, не прервало ли его что-то извне (ну или он сам).
Надеюсь, не запутал.
Что касается ((Task4)threads.get(3)).showWarning(), то эта строчка не нужна в принципе. Задача не просила запускать потоки, а просто обеспечить необходимую функциональность. Таким образом, метод main вообще может быть пустым.
... Продолжение во втором комменте, лимит знаков.
+2
hidden #598481
28 декабря 2018, 12:11
Но если мы все-таки хотим проверить, как работают наши потоки, мы их запускаем, как у тебя:
По условию, чтобы прервать четвертый поток, нужно выполнить в нем метод showWarning().
Чтобы мы могли это сделать, нам нужно к нему обратиться, для этого мы его получаем из списка:Надеюсь про индекс 3 объяснять не нужно. Но поскольку у нас в списке хранятся любые потоки (список объявлен как , мы не можем утверждать, что у любого элемента списка есть метод showWarning(): он есть только у потоков класса Task4, поэтому полученный поток мы должны сначала привести к типу Task4: и после этого уже у полученной конструкции вызвать метод showWarning():
Почему нельзя вызвать Task4.showWarning()
Метод showWarning() нестатический, его можно вызывать только у объекта класса, а не у самого класса.
или создав объект Task4 task4 = new Task4(); task4.showWarning()
Выполняя команду new ты создаешь новый объект, в данном случае новый поток. Поток, который уже существует, хранится у тебя в списке под индексом 3. Тебе нужно прервать именно его, а не новый поток того же класса.
Можно сделать так:Так ты возьмешь свой поток из списка и положишь в переменную task4, и потом вызовешь у объекта из переменной task4 нужный метод.
Нельзя сделать это без приведения типа т.к. threads.get() может вернуть любой тип Thread, необязательно Task4, поэтому класть в переменную Task4 нельз
+1
АлександрExpert
28 декабря 2018, 14:23
Я имею ввиду вместо threads.add(new Task4()); создать объект таким образом
0
АлександрExpert
28 декабря 2018, 14:28
что делает this
0
hidden #598481
28 декабря 2018, 14:52
объект создается только с ключевым словом new. Можно просто написать new Task4();, и это уже будет созданием нового объекта. Что с ним делать - это в принципе на совести программиста, но задача требует, чтобы в статическом блоке все потоки были добавлены в список, поэтому в main нужно работать с теми потоками, которые есть в списке, а не с новыми (new).
Оговорюсь еще раз, что вообще в main ничего писать не требуется, но если ты хочешь проверить как работают созданные потоки, бери их из списка, а не создавай новые.
Сам по себе код рабочий, ты можешь создать еще одну нить, запустить ее и прервать, вызвав showWarning(), ничего не подчеркивает
Только у меня Thread4 вместо Task4
this - это ссылка на объект, для которого запускается метод.
если ты пишешь task4.showWarning();, то this - это ссылка на task4, если ты пишешь ((Task4) threads.get(3)).showWarning();, то this - это ссылка на поток, который ты достал из списка ((Task4) threads.get(3)).
+1
АлександрExpert
28 декабря 2018, 15:29
Спасибо вроде разобрался
0
Дмитрий СоснинExpert
28 декабря 2018, 11:50
больше кода надо
0
Дмитрий СоснинExpert
28 декабря 2018, 12:00
хотя если допустить, что ранее было что-то вроде
то выражение ((Task4)threads.get(3)).showWarning(); можно трактовать как взять из листа ссылку на поток под индексом 3, сделать вид что она принадлежит классу Task4, и вызвать у него метод showMessage().
0
hidden #598481
28 декабря 2018, 12:20
скобочки конструктора забыл ;)
0
Дмитрий СоснинExpert
28 декабря 2018, 12:33
и одна лишняя треугольная скобка после new, но как пример сойдёт, а левую часть дак вообще буква в букву угадал )))
0
АлександрExpert
28 декабря 2018, 15:29
Спасибо
0