![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Aehn |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 64 Регистрация: 24.4.2008 Репутация: нет Всего: нет |
Есть класс myThread - наследник Thread
Запускаю его нормально, а вот чтобы остановить вызываю myClass.stop() на что компилятор ругается
Но, помнится, когда-то давно этот пример нормально шел. Так как его надежно остановить? Добавлено через 4 минуты и 54 секунды Все, вопрос решился. Есть метод interrupt() Это сообщение отредактировал(а) Aehn - 13.5.2008, 14:27 |
|||
|
||||
| $tatic |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 651 Регистрация: 28.1.2005 Репутация: нет Всего: 22 |
Aehn,
вообще-то это неправильно, документация предлагает сделать вот так: было
стало
|
||||
|
|||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 6 Всего: 93 |
Подниму тему. Что-то я так и не понял, как нормально прервать поток, раз stop() теперь deprecated?
У меня есть поток, который в фоновом режиме загружает из JPEG большую картинку (например 80 мегапикселей). Такая картинка занимает порядка 500 мегабайт в памяти и загружается около 7 секунд. Если вдруг на середине загрузки я узнал, что мне эта картинка не нужна, а нужна другая, то как мне прервать поток? Метод interrupt() не подходит, так как он не прерывает поток, а только выставляет соответствующий статус потока, который я не могу проверить пока картинка полностью не загрузится. А если вторая картинка тоже на 500 мегабайт, то обе сразу в память могут и не поместиться. Что делать? -------------------- Да. Именно так. |
|||
|
||||
| Hidrag |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 877 Регистрация: 9.4.2005 Где: JDK Репутация: 3 Всего: 25 |
Намудрили то
Как вариант: 1. Создаем класс, наследуем его от Thread. 2. В этом классе создаем паблик переменную логического типа. 3. В методе run этого класса определяем место или места где смотрим эту переменную и если она истина (или ложь, смотря как спрограммировать) то делаем break или return опять же в зависимости от того что делается в этом методе. 4. В классе откуда будет запускаться поток создаем объект выше созданного класса. 5. Вызываем у него метод start() - все поток запущен! 6. Если нужно "убить поток" у созданного объекта потока меняем логическую переменную, в потоке эта переменная проверится там где мы ее ранее определили и поток остановится. Что то вроде такого, все просто! Особенно удобно если в потоке крутится какой то цикл. -------------------- |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Hidrag, между прочим, Дрон не намудрил, он работает с interrupt, и на мой взгляд это куда правильней, чем плодить доп. логические переменные.
Случай, конечно, интересный. Я так же задавался вопросом, как можно без всяких проверок рубануть поток? Таким образом нам нужно писать потокозависимые компоненты, т.е. к примеру загрузчик изображения из сети, который каждые N байтов проверяет, актуальна ли еще его загрузка. |
|||
|
||||
| Hidrag |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 877 Регистрация: 9.4.2005 Где: JDK Репутация: 3 Всего: 25 |
и Тоже самое и получается -------------------- |
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 6 Всего: 93 |
Меня интересует мой конкретный случай. Общие подходы я отлично знаю, но вот в моём случае они не работают. В моём потоке и цикла никакого нет, упрощённо говоря он вообще состоит из вызова одного единственного метода из ImageIO, загружающего картинку. О том и речь :( Я предполагаю, что можно грузить картинку по частям (tiles), разбив её на прямоугольники размером в пару-тройку мегапикселей и потом собирать в одну большую... Но мне кажется, что помимо усложнения кода, это потребует дополнительного времени на обработку и увеличит расход памяти, так что в данном случае проще вызвать Thread.stop(). Ведь то, что он deprecated не означает, что он не работает? Или есть шанс, что потом они его вообще выкинут? Это сообщение отредактировал(а) Дрон - 26.5.2008, 12:04 -------------------- Да. Именно так. |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Именно, хотя уже какую версию этот stop тянется. |
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 6 Всего: 93 |
Эх... Хотя думаю, что всё равно не выкинут Но мне, скорее всего, придётся всё-таки по кускам картинку грузить, благо все соответствующие методы для этого есть. Главное, чтобы на быстродействие и память это не сильно влияло. -------------------- Да. Именно так. |
|||
|
||||
| Maksym |
|
|||
![]() . ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1456 Регистрация: 19.8.2005 Где: Odessa, Black Sea Репутация: 14 Всего: 62 |
Дрон
Думаю, нужно грузить картинку не метдами ImageIO, а каким-нибудь простым байтовым стримом, где ты в цикле выбирашь данные в буфер. Там есть возможность сделать любую проверку на каждой итерации и прерваться при необходимости. А потом, после окончания загрузки, целиком загруженные данные можно отдать в более высокоуровневые методы из ImageIO. |
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 6 Всего: 93 |
Там JPEG. Сам файл занимает, скажем, порядка 20-30 мегабайт и загрузить его в память -- один миг, проблема состоит в декодировании JPEG, которое и занимает основное время. Писать собственный декодер я пока не готов -- и так времени нет Я уже различными хитростям смог оптимизировать остальные операции с картинками, осталось только забороть загрузку. Это сообщение отредактировал(а) Дрон - 26.5.2008, 17:17 -------------------- Да. Именно так. |
|||
|
||||
| math64 |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2505 Регистрация: 12.4.2007 Репутация: 8 Всего: 72 |
|
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 6 Всего: 93 |
math64, это вроде не совсем то. Но в общем случае -- да, можно было использовать перегруженный InputStream, при условии что декодирование идёт вместе с чтением. А вот если сначала читается весь файл, а только потом декодируется, то этот способ не пойдёт -- как внутри устроен ImageIO я не знаю.
Свою проблему я решил даже проще -- как оказалось ImageReader из ImageIO умеет сообщать свой прогресс, и вот в обрабочик прогресса я и добавил проверку на то не был ли прерван поток. Так что с потоками пока разобрался. Всем отвечавшим спасибо Это сообщение отредактировал(а) Дрон - 27.5.2008, 13:48 -------------------- Да. Именно так. |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
interrupt по моему представлению, прерывает не выполнение потока, а ожидание. Если поток стоит в wait(), то interrupt() его разбудит. Если же поток выполняет последовательность команд, например, вычисления в цикле, то interrupt() никакого эффекта не даст - у потока нет никакого внутреннего флага, который он бы проверял на каждом шагу. Это дело программиста - "плодить доп. логические переменные", если надо. И это компетенция программиста ставить проверку флага в правильном месте: например, поток открыл соединение, потом проверил флаг, и обнаружил команду "умереть". Так перед смертью он должен открытое соединение закрыть. Освободить захваченные ресурсы. |
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 6 Всего: 93 |
Использование interrupt() избавляет от необходимости вводить дополнительную булевую переменную, потому что у потока есть метод isInterrupted() позволяющий проверить, требуется ли прервать выполнение. -------------------- Да. Именно так. |
|||
|
||||
| mindflyer |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 113 Регистрация: 20.10.2004 Где: Smolensk, Russia Репутация: 1 Всего: 4 |
Иногда лучше всё же добавлять свою переменную. Уже писал где-то на форуме - столкнулся с ситуацией, когда interrupt перехватывался в сторонней библиотеке, обрабатывался и сбрасывался флаг. В итоге, если interrupt был вызван, когда управление было не в моём коде, а в коде той библиотеки, то мой код вызывая inInterrupted() получал false и продолжал выполнение. |
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 6 Всего: 93 |
Хм. А вот это действительно возможно. -------------------- Да. Именно так. |
|||
|
||||
| COVD |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Спасибо, совсем забыл.
Это просто вредительство |
||||
|
|||||
| AlexeyVorotnikov |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 658 Регистрация: 18.6.2007 Где: Москва Репутация: 10 Всего: 18 |
У потока так же есть метод public static boolean interrupted() в описании которого сказано:
-------------------- RTFM! Три источника и три составные части Java: The Java Language Specification, Java Platform API Specification, The Java Virtual Machine Specification |
||||||||
|
|||||||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 17 Всего: 43 |
Спасибо. |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |