如何避免在 Java 中忙于旋转

Jos*_*osh 6 java multithreading mutex

我有一个多线程应用程序,其中一个线程向另一个线程发送消息。等待线程轮询消息并做出反应(处理锁)。像这样:

等待线程代码:

while(true)
{
  if(helloArrived())
    System.out.println("Got hello");
  if(byeArrived())
    System.out.println("Got bye");
  if(stopArrived())
    break;
}
Run Code Online (Sandbox Code Playgroud)

我想避免这种 CPU 占用技术,而是使用其他东西。有任何想法吗?

编辑:实际代码如下:

BlockingQueue<Mail> killMeMailbox = new LinkedBlockingQueue<Mail>();
BlockingQueue<Mail> messageMailbox = new LinkedBlockingQueue<Mail>();

public void run()
    {
        while(true)
        {
            if(killMeMailbox.size() > 0)
            {
                break;
            }
            if(messageMailbox.size() > 0)
            {
              System.out.println(messageMailbox.poll());
            }
        }
     }

public void receiveMail(Mail mail)
    {
        //kill
        if(mail.from == -1)
        {
            killMeMailbox.add(0);
        }
        else
        {
            //other
            try
            {
                messageMailbox.put(mail);
            }
            catch(Exception e)
            {
                System.out.println(e.getMessage());
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

Ste*_*n C 6

避免这种情况的正确方法是使用由 实现的等待/通知机制java.lang.Object,或 Java 类库提供的更高级别的并发机制之一:

(选择与您的特定用例最匹配的机制......)


使用Thread.sleep不是一个好的解决方案。虽然您减少了 CPU 负载(与轮询循环相比),但另一方面是您降低了响应能力。


我现在正在使用 BlockingQueue。但也许我做错了。我刚刚添加了上面的实际代码。你看到我的问题了吗?

是的。您正在以一种旨在避免阻塞的方式使用队列。那是错误的做法。您应该使用take()(它会阻塞直到条目可用)而不是poll(),并去掉测试队列大小的代码。

您的“killMeMailbox”内容似乎旨在让您停止等待邮件。您应该能够使用Thread.interrupt. (中断将解除take()呼叫阻塞...)