Message-processing-task在检测到客户端登录任务时应该停止处理新消息。但是,消息处理器应该在暂停之前完成它正在处理的任务。这基本上意味着客户端登录任务应该在消息处理器继续之前给消息处理器一个喘息空间(等待自己)。场景就是这个
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在处于相同执行路径的线程之间同步。
编辑 - 有一个消息处理线程。但是,可以有多个登录线程。
我想到的解决方案是使用Reentrant锁。那么在处理每条消息之前会发生什么,获取锁定并且消息处理器检查是否有任何客户端登录正在进行中。 AtomicInteger告诉我正在进行的登录请求的数量。如果正在进行多个登录请求,则通知处理器等待锁定条件。通知处理器发出信号以恢复其工作的条件是AtomicInteger计数必须降至0。 解决方案唯一需要注意的是,如果正在处理消息并且登录请求位于其中间,则登录线程不会等待。这就是我需要在客户端登录时需要另一个锁定的地方,当消息处理器处理完消息时必须释放该锁定。这使解决方案过于复杂,我想避免这种不必要的复杂性。 任何建议表示赞赏。
答案 0 :(得分:1)
使用Semaphore
(1个许可,公平性为真)的简单方法是在登录/消息处理任务之间共享一个。如果消息处理线程处于任务的中间,它将在登录任务可以处理之前完成(公平性将保证登录任务将在之后立即执行)。
如果有多个消息处理线程,这种方法将无法正常工作。
答案 1 :(得分:1)
我不确定我是否正确选择了这个,但是我会使用ThreadPoolExecutor
单线程,并在其中传递PriorityBlockingQueue
。您的所有任务都将转到该队列,登录任务将具有更高的优先级,因此它们将在任何message-processing
任务之前得到处理。
如果message-processing-task
正在进行中,它将在client-login-tasks
开始之前完成。这会是您需要的吗?