在Java中,将Thread.sleep(1)用于空闲线程是否有效?

Aut*_*tAM 10 java multithreading sleep

我的线程中有一个主循环,其中一部分测试空闲布尔值是否为真.如果是,它将调用Thread.sleep(1)循环的每次迭代.这是一种有效的方法吗?我的目标是让线程在空闲时占用最少的CPU.

Mik*_*uel 8

否.请Object.wait改为使用并确保在包含布尔值的对象上进行同步.如果你不同步而boolean不是volatile,你没有内存障碍,所以不能保证轮询线程会看到更改boolean.

根据javadoc:

此方法使当前线程(称为T)将自身置于此对象的等待集中,然后放弃此对象上的任何和所有同步声明.线程T因线程调度而被禁用,并且在发生以下四种情况之一之前处于休眠状态:

  • 一些其他线程调用notify此对象的方法,并且线程T恰好被任意选择为要被唤醒的线程.
  • 其他一些线程调用notifyAll此对象的方法.
  • 一些其他线程中断线程T.
  • ...

所以线程在等待通知时不会占用CPU.

下面的代码是一个简单的空闲标志,其中waitUntilIdle包含您的main方法可以调用的setIdle方法以及可以由另一个线程调用的方法.

public class IdleFlag {
  private boolean idle;

  public void waitUntilIdle() throws InterruptedException {
    synchronized (this) {
      while (true) {
        // If the flag is set, we're done.
        if (this.idle) { break; }
        // Go to sleep until another thread notifies us.
        this.wait();
      }
    }
  }

  public void setIdle() {
    synchronized (this) {
      this.idle = true;
      // Causes all waiters to wake up.
      this.notifyAll();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)