Java Thread.sleep()与Thread.onSpinWait
我有一个旋转等待循环,它正忙着等待设置标志。然而,这可能需要很多时间才能实现——几分钟,甚至几小时 将比从Java Thread.sleep()与Thread.onSpinWait,java,Java,我有一个旋转等待循环,它正忙着等待设置标志。然而,这可能需要很多时间才能实现——几分钟,甚至几小时 将比从线程#onSpinWait的更有效: 运行时可以采取措施来提高调用自旋等待循环构造的性能 Thread#sleep不执行此操作,而是将处理器释放到另一个可运行线程,直到其睡眠时间结束 如果我是你,我会重新设计你的系统,使用中断(事件)而不是轮询(忙等待),因为这将比线程#睡眠或线程#onSpinWait在这种情况下,睡眠和旋转锁都不是你想要的。睡眠是错误的选择,因为你不知道你需要睡多久。执行
线程#onSpinWait的更有效:
运行时可以采取措施来提高调用自旋等待循环构造的性能
Thread#sleep
不执行此操作,而是将处理器释放到另一个可运行线程,直到其睡眠时间结束
如果我是你,我会重新设计你的系统,使用中断(事件)而不是轮询(忙等待),因为这将比线程#睡眠
或线程#onSpinWait
在这种情况下,睡眠和旋转锁都不是你想要的。睡眠是错误的选择,因为你不知道你需要睡多久。执行某种类型的自旋锁循环是错误的,因为自旋锁是繁忙的等待,因此会消耗CPU周期,并且实际上只用于非常短的等待,以期望资源很快变得可用。这里要做的是设置一个信号量。让线程1等待线程2设置信号量 那么您想看一个关于及其长期可用的wait()
和notify/All()
方法的简短示例?(从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());
}
}
如果等待循环还有其他事情要做,Object.wait()
也有超时变量
因此,对象可以被wait()
-ed打开,然后等待线程可以被通知(一个等待线程通过notify()
或所有等待线程通过notifyAll()
),它们甚至不必相互了解。
由于等待和通知都必须发生在同步块内,因此可以安全地启动块,检查变量/标志/任何内容,并有条件地发出等待(这里没有显示这些结构)。。我不知道这些方法的存在-谢谢!