2014-11-28 3 views
0

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

1) message-processing-task is processing messages from a queue (one at a time) 
2) It detects a client-login in the middle of processing a message 
3) message-processing-task should complete processing the message before it waits for the client-login-task to complete. This is where the client-login-task must wait. 
4) client-login-task complete and signals message-processing-task 
5) message-processing-task goes about its business. 

Мой вопрос, есть ли готовые синхронизаторы между этими двумя нити, проводящие различные пути и все же должны ждать друг от друга? Мое понимание - Cyclic Barrier, Semaphore, CountDownLatch синхронизировать между потоками, которые находятся на одном пути выполнения.

EDIT- Существует один поток обработки сообщений. Тем не менее, может быть несколько потоков входа.

Решение, которое я имею в виду, это использовать блокировку ретентата. Итак, прежде чем обрабатывать каждое сообщение, происходит блокировка, и процессор обработки сообщений проверяет, есть ли какой-либо вход в систему клиента. AtomicInteger сообщает мне количество выполненных запросов на вход в систему. Если в настоящее время выполняется более одного запроса на вход, процессор уведомлений ожидает в состоянии блокировки. Условие, на которое уведомление-процессор сигнализируется о возобновлении своей работы, заключается в том, что счетчик AtomicInteger должен опуститься до 0. Единственное предостережение с решением заключается в том, что сообщение обрабатывается, и запрос на вход приходит в середине этого, то нить входа не ждет. Вот где мне понадобится еще одна блокировка на клиенте-входе, который должен быть выпущен, когда обработчик сообщения обработал сообщение. Это делает решение слишком сложным, и я хотел бы избежать этой ненужной сложности. Любые предложения оценены.

+0

Ну, любые из размещенных в глобальном местоположении могут ссылаться (и использоваться) на два отдельных потока. – markspace

ответ

1

Не уверен, что я правильно это выбрал, но я бы использовал ThreadPoolExecutor с одной нитью, передавая в ней PriorityBlockingQueue. Все ваши задачи перейдут в эту очередь, задачи входа будут иметь более высокий приоритет, поэтому все они будут обработаны перед любыми задачами message-processing.

Также, если message-processing-task находится в процессе, он будет завершен до того, как начнется client-login-tasks. Будет ли это то, что вам нужно?

+0

Я реализовал подход использования PriorityQueue. Как-то одна активность входа в систему была приемлемым решением. Много thnx! –

1

Простой подход с Semaphore (1 разрешение, справедливость true) заключается в совместном использовании одного из задач обработки логина/обработки сообщений. Если поток обработки сообщений должен находиться посреди задачи, он будет завершен до того, как будет выполнена процедура входа в систему (справедливость гарантирует выполнение задачи входа в систему сразу после нее).

Если есть несколько потоков обработки сообщений, этот подход не будет работать.

+0

Существует один поток обработки сообщений. Но может быть несколько потоков клиент-логин. –

+0

Тогда это решение позволит только одному клиенту войти в систему одновременно, что не очень эффективно. – Kayaman

Смежные вопросы