А>Как я уже писал выше. Между завершением предыдущей задачи и началом новой мне надо выполнять ряд действий по деинициализации. Для этого мне обязательно надо знать, что задача остановлена.
может это тоже задача?
Re[4]: Отмена выполнения задачи в отдельном потоке и FutureT
От:
Аноним
Дата:
18.03.09 16:21
Оценка:
Здравствуйте, mkizub, Вы писали:
M>Здравствуйте, Аноним, Вы писали:
А>>Как я уже писал выше. Между завершением предыдущей задачи и началом новой мне надо выполнять ряд действий по деинициализации. Для этого мне обязательно надо знать, что задача остановлена.
M>Ну тогда код задачи должен быть вроде M>
Здравствуйте, mkizub, Вы писали:
M>Здравствуйте, runtime2, Вы писали:
R>>При использовании Thread мне надо будет пересоздавать каждый раз поток. Экзекутор позволяет использовать один и тот же поток для запуска задач. Таск я использую для отмены и для работы с исключениями. Хотя может он и не к месту здесь.
M>Зачем пересоздавать? Создайте один раз и пусть он себе крутится. Вроде того, как это описано в javadoc-е для java.util.concurrent.BlockingQueue
В случае с Executor получается проще писать вспомогательные классы и прочее. Например, чтобы послать сообщение потокам об остановке достаточно вызвать shutdownNow() у реализации ExecutorService. В любом случае, рекомендуется использовать executors framework, вместо низкоуровневой работы с Thread.
Re[4]: Отмена выполнения задачи в отдельном потоке и FutureT
Здравствуйте, abch-98-ru, Вы писали:
А>>Как я уже писал выше. Между завершением предыдущей задачи и началом новой мне надо выполнять ряд действий по деинициализации. Для этого мне обязательно надо знать, что задача остановлена. A9R>может это тоже задача?
Да задача, но так как она связана с GUI, то должна выполняться в главном потоке.
Re[2]: Отмена выполнения задачи в отдельном потоке и FutureT
Здравствуйте, runtime2, Вы писали:
R>В любом случае, рекомендуется использовать executors framework, вместо низкоуровневой работы с Thread.
Понимаете, слово фреймворк переводится на русский как "каркас, остов". Так этот каркас может оказаться совсем не от вашей задачи.
Как вы заметили с get-ом, этот фреймворк не расчитан на подобное использование. Он расчитан на автоматическое выполнение независимых задач, последовательно или параллельно. Чтоб его пофиксить вы должны будете залезть туда очень глубоко, и не факт, что вообще сможете добиться этой функциональности.
ЗЫ Когда я читаю слова подобные "В любом случае, рекомендуется использовать" — у меня сразу желчь разливается. Тут в каждом слове ошибка. Не может быть единых рекомендаций на все (любые) случаи. И ссылки на неназванного, но видимо очень крутого, авторитета — особенно раздражают. Так что я умываю руки, что мог посоветовать, уже написал.
Здравствуйте, KRA, Вы писали:
KRA>Здравствуйте, Аноним, Вы писали:
А>>Написал класс А>>
А>>public class CallableControl<V> implements Callable<V> {
А>>
А>> public void waitDone() throws InterruptedException {
А>> //задача еще не начала выполняться
А>> if( latch.getCount() == 2 ) {
А>> return;
А>> }
А>> latch.await();
А>> }
А>>}
А>>
А>>То есть, вроде бы, все правильно. Только я не знаю насколько CallableControl корректен с точки зрения многопоточности.
KRA>Некорректен. Есть ситуация гонок в выделеной строке. Вполне возможен такая последовательность выполнения
KRA>
Здравствуйте, KRA, Вы писали:
KRA>Здравствуйте, Аноним, Вы писали:
А>>Написал класс А>>
А>>public class CallableControl<V> implements Callable<V> {
А>>
А>> public void waitDone() throws InterruptedException {
А>> //задача еще не начала выполняться
А>> if( latch.getCount() == 2 ) {
А>> return;
А>> }
А>> latch.await();
А>> }
А>>}
А>>
А>>То есть, вроде бы, все правильно. Только я не знаю насколько CallableControl корректен с точки зрения многопоточности.
KRA>Некорректен. Есть ситуация гонок в выделеной строке. Вполне возможен такая последовательность выполнения
KRA>
А>>>Как я уже писал выше. Между завершением предыдущей задачи и началом новой мне надо выполнять ряд действий по деинициализации. Для этого мне обязательно надо знать, что задача остановлена. A9R>>может это тоже задача?
R>Да задача, но так как она связана с GUI, то должна выполняться в главном потоке.
если "главный поток" — это edt и там что-то ждёт блокируясь — завершения другого потока — это не гуд. но — это отвлечение.
если принципиально делать надо в двух потоках — главном и вспомогательном, то имхо правильно — это два single thread executor-а — для главного и вспомогательного и message-passing — размещением тасков в них.
т.е. из главного запустили таску на loadImage в вспомогательном и отпустили главный. при появлении реквеста на новую задачу, отменяющую предыдущую, — сделали предыдущей(запущенной во вспомогательном) cancel — разместили во вспомогательном executor-е таску, проверяющую на свой старт, состояние предыдущей заканселленной таски + размещение деинициализующей таски на предыдущую в main потоке (по необходимости) + из main потока же в деиниц. таске или отдельно запустили новую задачу в вспомогательном ex.... и тд.
всё последовательно — но всё thread-ы работают не блокируясь. если же надо блокируясь в главном thread-e — то да — можно latch-ами и по разблокированию действововать дальше. но если и есть у вас там блокирование в gui, то, надеюсь, не в edt.
удач,
Re[6]: Отмена выполнения задачи в отдельном потоке и FutureT
Здравствуйте, abch-98-ru, Вы писали:
A9R>если принципиально делать надо в двух потоках — главном и вспомогательном, то имхо правильно — это два single thread executor-а — для главного и вспомогательного и message-passing — размещением тасков в них.
Главный поток, это действительно EDT. Кроме него есть два вспомогательных, которые завязаны на действия пользователя в GUI.
A9R>т.е. из главного запустили таску на loadImage в вспомогательном и отпустили главный. при появлении реквеста на новую задачу, отменяющую предыдущую, — сделали предыдущей(запущенной во вспомогательном) cancel — разместили во вспомогательном executor-е таску, проверяющую на свой старт, состояние предыдущей заканселленной таски + размещение деинициализующей таски на предыдущую в main потоке (по необходимости) + из main потока же в деиниц. таске или отдельно запустили новую задачу в вспомогательном ex.... и тд.
То есть получается EDT поток и два дополнительных потока?
A9R>всё последовательно — но всё thread-ы работают не блокируясь. если же надо блокируясь в главном thread-e — то да — можно latch-ами и по разблокированию действововать дальше.
Спасибо, теперь я знаю, что все делаю правильно
A9R>но если и есть у вас там блокирование в gui, то, надеюсь, не в edt.
Как я уже говорил в EDT, но в этом ничего нет страшного. Это блокировние происходить только как реакция на какое-то действие пользователя. Например, закрытие текущего документа (возможно с сохранением внесенных изменений) и переход к следующему. Для пользователя вполне естественно подождать несколько секунд.
Re[7]: Отмена выполнения задачи в отдельном потоке и FutureT
Здравствуйте, runtime2, Вы писали:
R>Как я уже говорил в EDT, но в этом ничего нет страшного. Это блокировние происходить только как реакция на какое-то действие пользователя. Например, закрытие текущего документа (возможно с сохранением внесенных изменений) и переход к следующему. Для пользователя вполне естественно подождать несколько секунд.
Одно дело ждать, когда бегут часики и при alt-tab происходит перерисовка и т.д., а другое дело когда весь UI поток заморожен. Последнее не есть хорошо.
Re[7]: Отмена выполнения задачи в отдельном потоке и FutureT
A9R>>если принципиально делать надо в двух потоках — главном и вспомогательном, то имхо правильно — это два single thread executor-а — для главного и вспомогательного и message-passing — размещением тасков в них. R>Главный поток, это действительно EDT. Кроме него есть два вспомогательных, которые завязаны на действия пользователя в GUI. A9R>>всё последовательно — но всё thread-ы работают не блокируясь. если же надо блокируясь в главном thread-e — то да — можно latch-ами и по разблокированию действововать дальше. R>Спасибо, теперь я знаю, что все делаю правильно
если надо заблокировать edt и отрубить перерисовки — то да