gpt4 book ai didi

java - 如果消息队列不为空,则始终运行处理线程

转载 作者:行者123 更新时间:2023-12-02 11:54:19 24 4
gpt4 key购买 nike

每当服务器接收到来自客户端的消息时,该消息就会被放入队列中。多个线程可以在队列中输入数据,但一次只能有一个线程从中读取/处理。只要队列中有消息,处理线程就应该处于 Activity 状态。我怎样才能做到这一点?

如果我将处理逻辑放在同步方法中,并为每个请求启动一个调用此方法的新线程,那么将所有这些线程都放在内存中等待轮到,这不是浪费资源吗?

另一方面,如果我使用单个处理线程,每个请求都尝试启动它(如果它尚未运行):

public void onMessage(String message) {
addToQueue(message);
synchronized (lock) {
if (!processingThread.isAlive())
processingThread.start();
}
}

// processing thread
public void process() {
while (true) {
String message = queue.poll();
synchronized (lock) {
if (message == null)
return;
}
// process message
}
}

如何确保不会遇到这种情况:

  1. 处理线程轮询队列中的下一个元素。它获得共享锁并进入同步块(synchronized block)。它检查并发现从队列中读取的元素为 null,因此队列为空。 线程释放锁,但其 isAlive 标志尚未设置为 false。
  2. 客户端请求到达,在队列中添加一条消息。接收方法获得锁,并进入其同步块(synchronized block)。处理线程仍然处于 Activity 状态,因此不需要启动它。该方法释放锁。
  3. 处理线程现已释放锁并终止。

在这种情况下,队列中将有一条未处理的消息。这种情况会发生吗?正如加粗这句话所暗示的那样,锁可以在线程死亡之前释放吗?

最佳答案

这是一个消费者/生产者问题。无需停止/启动处理线程(消费者)。它可以阻塞,等待队列中的消息。客户端线程(生产者)填充队列,notify() 消费者线程解除阻塞,删除消息并再次等待。这是一个例子https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html .

关于java - 如果消息队列不为空,则始终运行处理线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47703570/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com