Thread.sleep()vs Thread.onSpinWait

Tir*_*esi 2 java

我有一个忙等待的旋转等待循环 - 等待设置一个标志.但是,这可能需要花费大量时间才能实现 - 几分钟甚至几小时.

Thread.sleep()方法是不是更有效Thread.onSpinWait()

Jac*_* G. 6

文件Thread#onSpinWait:

运行时可以采取措施来提高调用自旋等待循环结构的性能.

Thread#sleep 不会这样做,而是将处理器释放到另一个可运行的线程,直到其休眠时间结束.

如果我是你,我会重新设计你的系统以使用中断(事件)而不是轮询(忙等待),因为这将导致比任何一个Thread#sleep或更好的性能提升Thread#onSpinWait.


tev*_*dar 2

那么您想看一个关于Object其长期可用的简短示例wait()notify/All()方法吗?(它们已经存在JLS 1.0中,从 20 多年前开始)

别说了:

public class NotifyTest {
  private boolean flag = false;
  public synchronized boolean getFlag() {
    return flag;
  }
  public synchronized void setFlag(boolean newFlag) {
    flag = newFlag;
    notifyAll();
  }

  public static void main(String[] args) throws Exception {
    final NotifyTest test = new NotifyTest();

    new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.printf("I am thread at %,d, flag is %b\n",
                          System.currentTimeMillis(), test.getFlag());
        synchronized (test) {
          try {
            test.wait();
          } catch (InterruptedException ie) {
            ie.printStackTrace();
          }
        }
        System.out.printf("I am thread at %,d, flag is %b\n",
                          System.currentTimeMillis(), test.getFlag());
      }
    }).start();

    System.out.printf("I am main at %,d, flag is %b\n",
                      System.currentTimeMillis(), test.getFlag());
    Thread.sleep(2000);
    test.setFlag(true);
    System.out.printf("I am main at %,d, flag is %b\n",
                      System.currentTimeMillis(), test.getFlag());
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您的等待循环还有其他事情要做,Object.wait()也有超时的变体。

因此,对象可以被wait()打开,然后可以通知等待线程(通过其中一个服务员notify()或通过所有服务员notifyAll()),并且它们甚至不必相互了解。
由于等待和通知都必须在同步块内发生,因此启动该块、检查变量/标志/任何内容并有条件地发出等待(只是这些结构未在此处显示)是安全且可能的。