С Новым годом! Форум программистов, компьютерный форум, киберфорум
Java
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 06.07.2023
Сообщений: 3
1

Прерывание Thread

28.11.2023, 20:32. Показов 1050. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class ThreadTest {
    public static volatile int numSeconds = 0;
 
    public static void main(String[] args) throws InterruptedException {
        RacingClock clock = new RacingClock();
        clock.start();
        Thread.sleep(3000);
        clock.interrupt();
    }
 
    public static class RacingClock extends Thread {
 
        public void run() {
            try {
                while (!Thread.currentThread().isInterrupted() && numSeconds < 100) {
                    System.out.print(numSeconds + " ");
                    Thread.sleep(100);
                    numSeconds++;//!!!!!!!!
                }
                System.out.println("Старт!");
            } catch (InterruptedException e) {
                System.out.print("Прервано!");
            }
        }
    }
}
Возможна ли ситуация, что поток main вызовет clock.interrupt() в момент операции инкремента numSeconds++ и условие
цикла while не выполнится и исключение не выбросится? Такое решение приподносится как верное. Число 100 установлено просто для примера что бы бросало исключение!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.11.2023, 20:32
Ответы с готовыми решениями:

Реагирование приложения на прерывание из IDE
Пытался гуглить данный вопрос, но либо нет ответа, либо скил гугления еще не прокачан. Собственно...

Проблема со Thread...
Narod, voznikla takaya vot problemka - est' nekiy klass, (sm. source), koiy obyazatel'no doljen...

Непонятки в Java. Chain method call. Thread.start() vs Thread.run()
Ребят, кто знает подскажите, изучаю Java уже 4 месяца, а до меня все не доходит вот к примеру такая...

Как исправить проблему с Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
Exception in thread &quot;JavaFX Application Thread&quot; java.lang.NullPointerException at...

9
1 / 1 / 0
Регистрация: 01.03.2024
Сообщений: 16
19.05.2024, 17:00 2
Очевидно да, такое может происходить. Это легко проверить, увеличив время выполнения код около инкремента. Например так:
Java
1
2
3
4
5
6
7
8
Thread.sleep(100);
numSeconds++;//!!!!!!!!
long i = 20000000L;
while (i > 0) {
  i *= 2;
  i /= 2;
  --i; 
}
Тогда в зависимости от быстродействия компьютера и значения в переменной i будут получаться примерно такие сообщения:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Старт!
или
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Прервано!

А решение преподносится как верное из-за корректного завершения потока в любом случае, в чем и есть смысл вызова interrupt().

Если что, то мой ответ не заслуживает большого доверия, ибо сам изучаю java только пятый день. Как раз читаю многопоточность.
0
681 / 290 / 75
Регистрация: 07.01.2023
Сообщений: 1,209
19.05.2024, 18:08 3
interrupt() ничего не прерывает кроме методов, которые описаны через throws InterruptedException (типа sleep())
Так что описанной вами ситуации быть не может вообще
0
1 / 1 / 0
Регистрация: 01.03.2024
Сообщений: 16
19.05.2024, 19:29 4
Хм, я скопировал код из темы как есть. Добавил 6 строк цикла после numSeconds++;//!!!!!!!!. И получил результаты попеременно с выбросом исключения, так и без него, на каждый запуск приложения разные. Так что ситуация точно может быть. Более того, она должна быть, так как, что мешает потоку выполнять инкремент переменной, когда главный поток вызывает interrupt()? Ничего. И вы скорее всего заблуждаетесь, говоря "interrupt() ничего не прерывает кроме методов, которые описаны через throws InterruptedException ..". Вызов interrupt() точно не прерывает, он возобновляет спящий поток и тот отрабатывает исключение обычным образом. Вместе с тем interrupt() должен установить флаг "прерван" в мониторе объекта (в данном случае clock). На этот флаг реагирует Thread.currentThread().isInterrupted() и поток завершается без получения исключения. Думаю вызов interrupt() должен 1) установить флаг для объекта и 2) возобновить выполнение потока, ассоциированного с объектом. Не важно спит поток или выполняется. Просто делает системный ОС вызов "возобновить".
0
681 / 290 / 75
Регистрация: 07.01.2023
Сообщений: 1,209
20.05.2024, 07:11 5
mavapo,
Потому что код написан криво.
Перепишите на
Java
1
2
3
4
5
6
7
8
9
10
System.out.println("Старт!");
while (!Thread.currentThread().isInterrupted() && numSeconds < 100) {
    System.out.print(numSeconds + " ");
    numSeconds++;
    try { Thread.sleep(100); } catch(InterruptedException e) { 
        System.out.println("Прервано!");
       break; 
    } 
}
System.out.println("Завершено на "+numSeconds);
и попинайте его вызовом interrupt()
0
1 / 1 / 0
Регистрация: 01.03.2024
Сообщений: 16
20.05.2024, 08:55 6
Переписал. Все то же самое.
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static class RacingClock extends Thread {
        private boolean Loop() {
            long i = 20000000L;
            while (i > 0) {
              i *= 2;
              i /= 2;
              --i; 
            }
            return true;
        }
        public void run() {
            System.out.println("Старт!");
            while (Loop() && !Thread.currentThread().isInterrupted() && numSeconds < 100) {
                System.out.print(numSeconds + " ");
                numSeconds++;
                try { Thread.sleep(100); } catch(InterruptedException e) { 
                    System.out.println("Прервано!");
                   break; 
                } 
            }
            System.out.println("Завершено на "+numSeconds);
        }
    }
Работает как без исключения так и с исключением. Раз на раз не приходится:
Старт!
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Завершено на 17
или
Старт!
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Прервано!
Завершено на 18

Только не просите убрать добавленный вызов метода с циклом. Я не собираюсь запускать программку 10 миллионов раз, чтобы выловить однократное срабатывание условия завершения потока через флаг завершения(Thread.currentThread().isInterrupted()).
0
681 / 290 / 75
Регистрация: 07.01.2023
Сообщений: 1,209
20.05.2024, 13:17 7
Цитата Сообщение от mavapo Посмотреть сообщение
Завершено на 17
Цитата Сообщение от mavapo Посмотреть сообщение
Завершено на 18
И чем это вас удивляет? Первый раз interrupt() сработал, выставил флаг isInterrupted, вы его в условии while перехватили и завершили поток. Сообщения "прервано" нет.
Второй раз inetrrupt() был вызыан во время sleep, возбудил исключение, флаг isInterrupted не устанавливался, и мы свалили из потока по исключению. (сообщение "Прервано").
Так что все просто понятно и логично. Каких вы чудес ждете?
0
1 / 1 / 0
Регистрация: 01.03.2024
Сообщений: 16
20.05.2024, 14:35 8
AzathtotТак что все просто понятно и логично. Каких вы чудес ждете?
Чудес не ожидается. Просто код, как вы предлагали, без рабочего цикла по времени схожего со временем sleep(100) показал бы только исключение, ибо вероятность выйти через флаг существует, но близка к 0.
AzathtotВторой раз inetrrupt() был вызван во время sleep, возбудил исключение, флаг isInterrupted не устанавливался
Думаю interrupt() флаг устанавливает всегда и к исключению отношения не имеет. Исключение возбуждает sleep() или join(0 и т.д. Если попытаться привести совсем убогий псевдо-логический код, то как-то так:
Java
1
2
3
4
5
public static void sleep(long millis) throws InterruptedException {
    Системный ОС вызов -> Sleep(millis);
    if (мы проснулись, а время спать еще не вышло)
        throw new InterruptedException(..);
}
Но это в общем мелочи. Наверно тему можно закрывать
0
681 / 290 / 75
Регистрация: 07.01.2023
Сообщений: 1,209
20.05.2024, 15:28 9
Цитата Сообщение от mavapo Посмотреть сообщение
Думаю interrupt() флаг устанавливает всегда и к исключению отношения не имеет.
Читаем тут
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.

If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.

If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.

If none of the previous conditions hold then this thread's interrupt status will be set.
0
1 / 1 / 0
Регистрация: 01.03.2024
Сообщений: 16
20.05.2024, 16:30 10
Ха, ну давайте документацией померяемся
Вот например выдержка из https://docs.oracle.com/javase... rrupt.html
The Interrupt Status Flag

The interrupt mechanism is implemented using an internal flag known as the interrupt status. Invoking Thread.interrupt sets this flag. When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.

By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.
Из предпоследнего предложения следует, что методы типа sleep() должны очищать interrupt status flag. Эти ведь методы завершаются выбросом исключения. Не так ли? Это логично, sleep() очистил флаг и выбросил исключение.

В той ссылке, что вы предложили описывается то же самое, т.е. поведение к которому приведет вызов interrupt(). А не то, что этот вызов делает внутри своего кода. Примерно так: "..затем статус прерывания будет очищен и они (функции sleep() и т.д.) получат InterruptedException".

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

Моя версия мне нравится больше. А именно: interrupt() устанавливает флаг и возобновляет спящий поток, а sleep() выбрасывает исключение (если есть основания) и очищает флаг (если условие исключения случилось). Это логично и легко реализуемо.
0
20.05.2024, 16:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.05.2024, 16:30
Помогаю со студенческими работами здесь

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException при создании Label
Пытаюсь написать чат по видео, в видео писали на Swing, я решил на JavaFX сразу начать учиться....

Jogl ошибка: Exception in thread "Thread-0" java.lang.UnsatisfiedLinkError: Can't load library: /Users/maga/IdeaProjects
При запуске программы на маке выдает ошибку, хотя тот же код с теми же подключенными библиотеками...

Ошибка Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
package sample; import java.sql.Connection; import java.sql.DriverManager; import...

Почему когда фоновый thread "спит" я не могу убить main thread ?
Привет! Делаю гуй на swing'e, для реализации долговременной задачи создал второй поток. В этом...

Ошибка Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
Вот что хочу сделать HBox hbox = new HBox(5); hbox.setAlignment(Pos.CENTER);...

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException при создании новой Tab или окна
Доброго времени суток, уважаемые форумчане и форумчанки! Не бросаю попытки разобраться с JavaFX...

Exception in thread "Thread-4,9,11,12,13" java.lang.IllegalMonitorStateException
Пассажиров, прибывших на трех (четырех, пяти) самолетах одновременно, развозят микроавтобусы....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru