我有一个自旋等待循环,它正在忙等待标志被设置。然而,这可能需要很长时间 - 几分钟甚至几小时。
我有一个自旋等待循环,它正在忙等待标志被设置。然而,这可能需要很长时间 - 几分钟甚至几小时。
根据Thread#onSpinWait的文档:
运行时可能会采取措施以提高调用自旋等待循环结构的性能。
Thread#sleep
不会这样做,而是释放处理器给其他可运行线程,直到其睡眠时间已过。
如果我是你,我会重新设计你的系统以使用中断(事件)而不是轮询(忙等待),因为这将比Thread#sleep
或Thread#onSpinWait
都有更好的性能提升。
在这种情况下,你既不需要睡眠也不需要自旋锁。 睡眠是错误的选择,因为你不知道需要多长时间才能醒来。 使用自旋锁循环也是错误的,因为自旋锁是忙等待,会消耗CPU周期,并且只适用于非常短的等待,以期望资源变得非常快速可用。 在这里,你需要设置一个信号量。 让线程1等待线程2设置信号量。
Object
及其长期可用的wait()
和notify/All()
方法的简短示例吗?(它们已经在20多年前的JLS 1.0中存在了)。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()
,然后等待线程可以被通知(通过notify()
中的其中一个等待者或通过notifyAll()
中的所有等待者),它们甚至不必彼此了解。