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

Прерывание Thread

28.11.2023, 20:32. Показов 1329. Ответов 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.11.2023, 20:32
Ответы с готовыми решениями:

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

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

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

9
 Аватар для mavapo
1 / 1 / 0
Регистрация: 01.03.2024
Сообщений: 16
19.05.2024, 17:00
Очевидно да, такое может происходить. Это легко проверить, увеличив время выполнения код около инкремента. Например так:
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
 Аватар для Azathtot
736 / 334 / 88
Регистрация: 07.01.2023
Сообщений: 1,416
19.05.2024, 18:08
interrupt() ничего не прерывает кроме методов, которые описаны через throws InterruptedException (типа sleep())
Так что описанной вами ситуации быть не может вообще
0
 Аватар для mavapo
1 / 1 / 0
Регистрация: 01.03.2024
Сообщений: 16
19.05.2024, 19:29
Хм, я скопировал код из темы как есть. Добавил 6 строк цикла после numSeconds++;//!!!!!!!!. И получил результаты попеременно с выбросом исключения, так и без него, на каждый запуск приложения разные. Так что ситуация точно может быть. Более того, она должна быть, так как, что мешает потоку выполнять инкремент переменной, когда главный поток вызывает interrupt()? Ничего. И вы скорее всего заблуждаетесь, говоря "interrupt() ничего не прерывает кроме методов, которые описаны через throws InterruptedException ..". Вызов interrupt() точно не прерывает, он возобновляет спящий поток и тот отрабатывает исключение обычным образом. Вместе с тем interrupt() должен установить флаг "прерван" в мониторе объекта (в данном случае clock). На этот флаг реагирует Thread.currentThread().isInterrupted() и поток завершается без получения исключения. Думаю вызов interrupt() должен 1) установить флаг для объекта и 2) возобновить выполнение потока, ассоциированного с объектом. Не важно спит поток или выполняется. Просто делает системный ОС вызов "возобновить".
0
 Аватар для Azathtot
736 / 334 / 88
Регистрация: 07.01.2023
Сообщений: 1,416
20.05.2024, 07:11
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
 Аватар для mavapo
1 / 1 / 0
Регистрация: 01.03.2024
Сообщений: 16
20.05.2024, 08:55
Переписал. Все то же самое.
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().isInte rrupted()).
0
 Аватар для Azathtot
736 / 334 / 88
Регистрация: 07.01.2023
Сообщений: 1,416
20.05.2024, 13:17
Цитата Сообщение от mavapo Посмотреть сообщение
Завершено на 17
Цитата Сообщение от mavapo Посмотреть сообщение
Завершено на 18
И чем это вас удивляет? Первый раз interrupt() сработал, выставил флаг isInterrupted, вы его в условии while перехватили и завершили поток. Сообщения "прервано" нет.
Второй раз inetrrupt() был вызыан во время sleep, возбудил исключение, флаг isInterrupted не устанавливался, и мы свалили из потока по исключению. (сообщение "Прервано").
Так что все просто понятно и логично. Каких вы чудес ждете?
0
 Аватар для mavapo
1 / 1 / 0
Регистрация: 01.03.2024
Сообщений: 16
20.05.2024, 14:35
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
 Аватар для Azathtot
736 / 334 / 88
Регистрация: 07.01.2023
Сообщений: 1,416
20.05.2024, 15:28
Цитата Сообщение от 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
 Аватар для mavapo
1 / 1 / 0
Регистрация: 01.03.2024
Сообщений: 16
20.05.2024, 16:30
Ха, ну давайте документацией померяемся
Вот например выдержка из 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
20.05.2024, 16:30
Помогаю со студенческими работами здесь

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

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
При запуске программы на маке выдает ошибку, хотя тот же код с теми же подключенными библиотеками работает на windows Среда Intellij...

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

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


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Миграция монолита в Event-Driven микросервисную архитектуру на C#
stackOverflow 11.04.2025
Монолитная архитектура – классический подход к разработке программного обеспечения. Это приложение, построенное как единое целое, где все компоненты тесно связаны между собой. Большинство проектов. . .
Go в Kubernetes: Управление ресурсами
golander 11.04.2025
Разработчики Go-приложений в Kubernetes часто сталкиваются с неожиданными проблемами производительности и даже внезапными отказами контейнеров. Причина этого кроется в особенностях взаимодействия. . .
Агрегаты и сущности в DDD микросервисах
Javaican 10.04.2025
Разработка современных программных систем часто приводит на распутье: монолит или микросервисы? Даже при выборе микросервисной архитектуры многие команды сталкиваются с проблемой правильного. . .
Многопоточность в C#: Task и параллельное программирование
UnmanagedCoder 10.04.2025
Современные процессоры уже давно перестали наращивать тактовую частоту в пользу увеличения количества ядер. Это создало интересную ситуацию: разработчики, привыкшие к последовательному. . .
Линейное решение нелинейной задачи будет иметь приблизительный результат вычисления для метода обработки данных из double buffering.
Hrethgir 10.04.2025
Вообще изначально я пренебрёг квадратурой числа, но потом понял, что для вычисления приблизительного значения - сгодится, формулу можно будет корректировать по ходу. Это потому что прямое соотношение. . .
Переменные в Python
py-thonny 10.04.2025
Переменная в программировании — это символическое имя, связанное с областью памяти, в которой хранится значение. Она позволяет получать доступ к данным через понятные человеку идентификаторы, а не. . .
Многопоточность в C#: Task и асинхронные операции
UnmanagedCoder 10.04.2025
Многопоточность позволяет выполнять несколько операций одновременно, что важно для решения двух основных задач: повышения скорости выполнения вычислительно-сложных операций и сохранения отзывчивости. . .
Запуск контейнеров Docker на ARM64
Mr. Docker 09.04.2025
Появление таких решений, как Apple M1/ M2, AWS Graviton, Ampere Altra и Raspberry Pi, сделало использование ARM-систем обыденностью для многих разработчиков и DevOps-инженеров. При этом Docker,. . .
Vue SFC компонент на PHP с Fusion
Jason-Webb 09.04.2025
PHP на сервере и JavaScript на клиенте — классическое сочетание, которое, несмотря на свою эффективность, создает определенный когнитивный диссонанс при разработке. В этом контексте появляются. . .
TypeScript vs JavaScript: Отличия и когда что использовать
Reangularity 09.04.2025
JavaScript появился в 1995 году как творение Брендана Эйха и быстро стал основой интерактивности в вебе. За свою историю он прошел путь от простого языка для манипуляций с DOM до полноценной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер