简体   繁体   English

如何避免在Java中忙于旋转

[英]How to avoid busy spinning in Java

I have a multi-threaded application where a thread sends a message to another thread. 我有一个多线程应用程序,其中一个线程将消息发送到另一个线程。 The waiting thread polls for the message and reacts (locks are handled). 等待线程轮询消息并做出反应(处理锁定)。 Like this: 像这样:

Waiting thread code: 等待线程代码:

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

I want to avoid this cpu hogging technique and use something else instead. 我想避免这种cpu占用技术,而是使用别的东西。 Any ideas? 有任何想法吗?

Edit: The actual code is below: 编辑:实际代码如下:

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());
            }
        }
    }

The correct way to avoid this is to use the wait/notify mechanism implemented by java.lang.Object , or one of the higher level concurrency mechanisms provided by the Java class libraries: 避免这种情况的正确方法是使用java.lang.Object实现的wait / notify机制,或者Java类库提供的更高级别的并发机制之一:

(Pick the mechanism that is the best match for what your specific use-case ...) (选择与您的具体用例最匹配的机制......)


Using Thread.sleep is not a good solution. 使用Thread.sleep不是一个好的解决方案。 While you reduce CPU load (compared with a polling loop), the flip-side is that you reduce responsiveness. 虽然您减少了CPU负载(与轮询循环相比),但另一方面是您降低了响应速度。


I'm using a BlockingQueue now. 我现在正在使用BlockingQueue。 But maybe I'm doing it incorrectly. 但也许我做错了。 I just added the actually code above. 我刚刚添加了上面的实际代码。 Do you see my problem? 你看到我的问题了吗?

Yea. 是啊。 You are using the queue in a way that is designed to avoid blocking. 您正在以避免阻止的方式使用队列。 That's the wrong approach. 这是错误的做法。 You should use take() (which will block until an entry becomes available) instead of poll() , and get rid of the code that tests the queue size. 您应该使用take() (它将阻塞直到条目可用)而不是poll() ,并删除测试队列大小的代码。

Your "killMeMailbox" stuff seems to be designed to allow you to stop waiting for mail. 您的“killMeMailbox”内容似乎旨在让您停止等待邮件。 You should be able to implement that using Thread.interrupt . 您应该能够使用Thread.interrupt实现它。 (An interrupt will unblock a take() call ...) (中断将取消阻止take()调用...)

You're doing busy waiting . 你正在忙着等待 You should never do that because it wastes CPU cycles. 你永远不应该这样做,因为它会浪费CPU周期。 A thread or process waiting for some event should be in blocked state . 等待某个事件的线程或进程应处于阻塞状态 Here are possible ways to achieve this: 以下是实现此目的的可能方法:

If you can reformulate your problem in terms of task-executor then consider using a SingleThreadExecutor . 如果您可以根据任务执行器重新表述您的问题,那么请考虑使用SingleThreadExecutor If you need something more exotic - either a concurrent queue or even wait()/notify() . 如果您需要更具异国情调的东西 - 并发队列甚至是wait()/ notify()

Have you tried to put some Thread.sleep to avoid executing the while loop constantly? 您是否尝试过一些Thread.sleep以避免不断执行while循环? It will liberate CPU for your other threads and avoid hogs 它会为你的其他线程释放CPU并避免生猪

http://docs.oracle.com/javase/tutorial/essential/concurrency/sleep.html http://docs.oracle.com/javase/tutorial/essential/concurrency/sleep.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM