Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: количество потоков  (Прочитано 31592 раз)
0 Пользователей и 1 Гость смотрят эту тему.
asdas
Интересующийся

ru
Offline Offline

« : 09-12-2010 16:08 » 

Как определить количество запущенных потоков?
нужно чтобы поток не выполнял действия пока есть другие потоки.

У меня в случае если пользователь нажмет быстро на кнопку второй раз запускается тот же процесс  И в критической секции происходит deadlock. И соответственно при входе в критическую секцию в случае если запущено 2 потока второй должен подождать.


Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 09-12-2010 16:57 » 

Критическая секция - это по определению участок, который проходит в один момент времени лишь один поток, а все остальные ждут на входе.

Вопрос о количестве запущенных потоков к описанной проблеме не относится. Однако в природе существует такой объект синхронизации, как семафор, который реализует подсчёт пользователей и ограничивает это число. Не уверен, что он есть в Java, но можно и без него обойтись.

Покажи свой код критической секции. Поскольку складывается впечатление, что ты допустил ошибку в её программировании.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 09-12-2010 17:04 » 

с помощью критической секции тоже можно организовать семафор
Записан

asdas
Интересующийся

ru
Offline Offline

« Ответ #3 : 09-12-2010 17:19 » 

Вообще код достаточно большой, в основном не мной написанный
Нажатие на кнопку долго обрабатывается и если пользователь сразу же нажмет второй раз запускается второй одинаковый процесс.
Как мне можно на несколько секунд приостановить выполнение второго потока перед критической секцией?
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 09-12-2010 19:10 » 

asdas,

В Java есть пакет java.util.concurrent http://download.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html
В этом пакете множество классов, упрощающих разработку многопоточных приложений.

Однакож я не понял одного - что значит "запускается второй одинаковый процесс"? Может быть, речь идет о запуске ещё одного потока?

Цитата
Как мне можно на несколько секунд приостановить выполнение второго потока перед критической секцией?
Обернуть код критической секции в конструкцию synchronised(lock) { }
где lock - произвольный объект, хоть this.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 09-12-2010 19:13 » 

asdas, ещё раз повторяю, что при вхождении в критическую секцию, уже занятую одним потоком, все остальные потоки останавливаются автоматически. Ничего для этого делать не надо.

Что действительно надо - так это правильно описать критическую секцию. Поэтому приведи свой код критической секции в точках входа и выхода из неё. Без твоего кода разговор беспредметный - либо ты неправильно понимаешь и описываешь свою ошибку (дело не в критических секциях), либо у тебя неправильно реализована критическая секция.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
asdas
Интересующийся

ru
Offline Offline

« Ответ #6 : 10-12-2010 16:16 » 

мда... synchronised(this) уже сделан
Видимо меня переклинило чутка
Здесь просто нажатие очень долго обрабатывается - много методов и если второй раз нажать быстро, то нормальное выполнение приложения заканчивается.
Надо видимо запретить обработку кнопки до завершения первой обработки
как это проще всего сделать?
Здесь все находится в разных классахю

 

Добавлено через 1 час, 40 минут и 8 секунд:
в принципе разобрался
всем спасибо
« Последнее редактирование: 10-12-2010 17:56 от asdas » Записан
Asafj
Интересующийся

ru
Offline Offline

« Ответ #7 : 12-12-2010 12:00 » 

А вообще, если система долго обрабатывает нажатие и затем падает при быстро повторном нажатии - такое часто бывает?
И нормальное здесь решение -  сделать переенную public static boolean - чтобы узнавать состояние из другого класса?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 12-12-2010 14:01 » 

Asafj, сделать флажок - нормально, а почему static?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 12-12-2010 14:04 » 

Думаю, что если внешнее действие в флагом - только чтение, то лучше делать его скрытым и завести метод для его чтения. Надежнее.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Asafj
Интересующийся

ru
Offline Offline

« Ответ #10 : 12-12-2010 14:16 » 

Да. как вариант
спс
Записан
asdas
Интересующийся

ru
Offline Offline

« Ответ #11 : 18-12-2010 12:46 » 

А еще по этой теме вопрос:
Как мне здесь лучше прочитать значение флага:
Вот у меня так : while(Update) {a();}
но если Update=false
a() пропускается
Какие здесь есть варианты?
туплю я что-то по-черному..
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 18-12-2010 13:10 » 

asdas, а что требуется?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
asdas
Интересующийся

ru
Offline Offline

« Ответ #13 : 18-12-2010 13:13 » 

требуется подождать пока Update не станет =true и тогда уже выполнять a()
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 18-12-2010 13:24 » 

while (Update);
a();

Только в реальной программе в многозадачной среде такое ожидание не допустимо - в цикл нужно добавить функцию пропуска (что-то типа yeld())
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 18-12-2010 23:43 » 

asdas,

по хорошему вам нужен примитив синхронизации CountDownLatch
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Asafj
Интересующийся

ru
Offline Offline

« Ответ #16 : 19-12-2010 10:39 » 

А чем отличаются записи:
while (Update);
a();

while(Update) {a();}
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 19-12-2010 11:05 » 

А чем отличаются записи:
while (Update);
a();

while(Update) {a();}

Первый случай эквивалентен такой записи:
Код: (Java)
while(Update) {}
a();
Разница понятна?
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Asafj
Интересующийся

ru
Offline Offline

« Ответ #18 : 19-12-2010 11:56 » 

Да, спасибо, разница понятна. В принципе это мне и надо.
Только здесь наверное 
while (!Update);
a();
Вот только из этого метода a() вызывается метод другого класса и создается поток.
Следовательно, в a() что-то типа sleep вызвать нельзя
Или все-таки  {} проканает здесь?
« Последнее редактирование: 19-12-2010 12:11 от Asafj » Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 19-12-2010 14:44 » new

Asafj, если вам нужно ждать события, которое произойдет в другом потоке, то while(!Update) - худшее, что можно придумать.

В Java с самого рождения разработан механизм wait - notify. Для отправки сигнала из потока 1 в поток 2 оба потока используют общий объект, я назову его signal (тип Object)
Поток 1, когда ему нужно отправить сигнал, использует такой код:
Код:
synchronized(signal) { signal.notify(); }
Поток 2 ожидает сигнал:
Код:
synchronized(signal) { signal.wait(); }

Недостаток этого решения в том, что второй поток должен вызвать wait до того, как первый отправит notify, в противном случае второй поток будет ждать бесконечно.

Более безопасным в этом смысле является CountDownLatch. Поток, который ждет сигнала, вызвает
Код: (Java)
latch.await();
Поток, который посылает сигнал, делает
Код: (Java)
latch.countDown();

Недостаток этого решения в том, что сигнал можно отправить только один раз.

Наиболее общий способ - воспользоваться синхронизированными контейнерами. Например ArrayBlockingQueue или SynchronousQueue
Поток, который ждет сигнал, вызвает
Код: (Java)
queue.take();
Поток, отправляющий сигнал, вызывает
Код: (Java)
queue.offer(x);
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines