Классическая задача ассинхронных потоков

Ответить
Nyashka
Сообщения: 40
Зарегистрирован: 19 мар 2013, 13:06

Классическая задача ассинхронных потоков

Сообщение Nyashka » 04 мар 2014, 11:37

Здравствуйте
Задача классическая. Есть два потока выполняющих какую то работу, и по завершению вызывающие метод workDone(this) известного им обоим одного экземпляра планировщика. Данный метод выполняемый в двух разных потоках запускает впоследствии некий другой поток если это не сделали до него. Проблема в том что эти начальные два потока могут завершить выполнение одновременно, следовательно код будет выполнен параллельно, и оба проскочат в выставленную блокировку типа:

Код: Выделить всё

if(!blocked){
blocked=true;
startNewTherad();
}

в результате чего будет сформировано два потока вместо одного.
Делать отдельный таймер сидящий в потоке планировщика и опрашивающий каждую милисекунду классы вышеизложенных потоков кажется не совсем разумным. Быть может есть более красивое решение известное андроид сообществу?


Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Классическая задача ассинхронных потоков

Сообщение Foenix » 04 мар 2014, 12:10

Про потоки теорию читай! Синхронизированные методы писать надо.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Nyashka
Сообщения: 40
Зарегистрирован: 19 мар 2013, 13:06

Re: Классическая задача ассинхронных потоков

Сообщение Nyashka » 04 мар 2014, 12:20

adarash писал(а):Handler?
Именно об обработчике и подумал когда предположил что есть более простое решение задачи, ведь обработка сообщений, во первых, выполняется в потоке самого обработчика, во вторых, делается последовательно. Однако ни разу не работал с ними, поэтому поинтересовался здесь.

Аватара пользователя
adarash
Сообщения: 333
Зарегистрирован: 17 июл 2013, 09:59

Re: Классическая задача ассинхронных потоков

Сообщение adarash » 04 мар 2014, 12:29

Ничего сложного. Постишь ему код в обертке Runnable и он их выполняет в порядке очереди (или с задержкой становления в очередь) и все. Один вперед другого не полезет.

Аватара пользователя
Mikhail_dev
Сообщения: 2386
Зарегистрирован: 09 янв 2012, 14:45
Откуда: Самара

Re: Классическая задача ассинхронных потоков

Сообщение Mikhail_dev » 04 мар 2014, 18:44

Слушайте Инну, она правильно указала про синхронизированне потоки. Каким тут боком Handler, ума не приложу.

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Классическая задача ассинхронных потоков

Сообщение Foenix » 04 мар 2014, 19:24

m090050 писал(а):Слушайте Инну, она правильно указала про синхронизированне потоки. Каким тут боком Handler, ума не приложу.
Миша, автор совершенно верно в названии упомянул слово "классическая", а хочет изобрести велосипед. Это уже даже не удивляет :roll:
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
altwin
Сообщения: 1951
Зарегистрирован: 13 ноя 2013, 14:46

Re: Классическая задача ассинхронных потоков

Сообщение altwin » 05 мар 2014, 14:59

Nyashka писал(а):Здравствуйте
Задача классическая. Есть два потока выполняющих какую то работу, и по завершению вызывающие метод workDone(this) известного им обоим одного экземпляра планировщика. Данный метод выполняемый в двух разных потоках запускает впоследствии некий другой поток если это не сделали до него. Проблема в том что эти начальные два потока могут завершить выполнение одновременно, следовательно код будет выполнен параллельно, и оба проскочат в выставленную блокировку типа:

Код: Выделить всё

if(!blocked){
blocked=true;
startNewTherad();
}

в результате чего будет сформировано два потока вместо одного.
Делать отдельный таймер сидящий в потоке планировщика и опрашивающий каждую милисекунду классы вышеизложенных потоков кажется не совсем разумным. Быть может есть более красивое решение известное андроид сообществу?
Lock() ?
http://stackoverflow.com/a/4201734/2611075
P.S. полезно для почитать: Java Concurrency in Practice
и посмотреть: http://www.youtube.com/watch?v=s032s29- ... -qJdf38oKp
Изображение

Nyashka
Сообщения: 40
Зарегистрирован: 19 мар 2013, 13:06

Re: Классическая задача ассинхронных потоков

Сообщение Nyashka » 18 авг 2014, 11:14

Спасибо всем за советы. Handler исправно функционировал до тех пор пока не понадобилось вынести его работу в отдельный поток, под вышеописанную задачу он вполне подходил. Более короткое и менее требовательное решение подсказали в остальных комментариях, а именно через Lock();
На всякий случай приведу код данного решения, на случай если кому то понадобится решить подобную задачу:

Код: Выделить всё

Lock lock = new ReentrantLock();
	if (lock.tryLock()) {
	    try {
	        if (!block) {
		    	block = true;
		    	// делаем что хотели
	        }
	    } finally {
	    	lock.unlock();
	    }		
	}
Возможно, на месте ReentrantLock(); можно подставить блокировщики другого типа. Вопрос разобрал не до конца, но даже так оно работает

Ответить