2015-05-11 3 views
1

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

... 
someService.doStuff(); 
otherService.doStuff(); 
//all services finished 
sendOutNotification(); 

Проблема заключается в том, что некоторые из этих услуг стреляя свою работу асинхронно и возвращения из DoStuff() немедленно, не дожидаясь завершения этой работы. Поскольку мой текущий поток просто вызывает эти методы службы, вместо того, чтобы владеть любыми фактическими исполнителями потоков, которые эти службы создают и запускают, кажется, что нет способа узнать, когда потоки, запущенные командой doStuff(), закончены.

Есть ли способ обойти это? Или есть проблема с дизайном, связанная с асинхронными исполнениями без ожидания на любом уровне (кроме верхнего)?

+2

это асинхронный режим, поэтому вам понадобится функция callbank, которую могут выполнять задания при их завершении. или перейдите в цикл опроса и задайте флажок, когда они будут выполнены. –

+0

API должен предоставить способ оповестить о завершении действия. – ZhongYu

ответ

0

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

Достойный способ приблизиться к этому - выполнить свои задачи через ExecutorService и предоставить результирующие объекты Future основной теме в качестве ручек. То есть, ваши методы doStuff() вернут их. Ваш основной метод собирает Future s, и когда придет время, он может опросить через Future.isDone(), блок по завершении через Future.get() и другие.

0

Лучший способ сделать это - использовать «обратные вызовы». Поэтому, когда вы вызываете внешнюю службу, отправляйте слушателей услуг (если внешняя служба поддерживает этот тип контракта.) Обратные вызовы или слушатели вызывается внешней службой при завершении.

В противном случае вы можете использовать эти API с фьючерсами. Используя .get(), вы можете проверить статус завершения. Чтобы синхронизировать их операции, вы можете использовать защелку обратного отсчета, чтобы при возврате всех потоков защелка обратного отсчета становилась 0, и вы можете принимать действия.

0

См: http://markusjais.com/understanding-java-util-concurrent-completionservice/

Может быть Завершение Сервис Java может делать вещи для и если Lib DonT, В спины поддержки вызовов.

Задайте все свои задачи doStuff для завершения службы и используйте take() для выполнения всех задач. Как только take() возвращается для всех отправленных задач (который блокируется, если в очереди нет очереди, которую завершает служба завершения после завершения задачи).

После того, как take() вернется для всех задач, вы можете активировать уведомление.