Java sleep会导致自旋循环永远循环
考虑以下代码:Java sleep会导致自旋循环永远循环,java,java-14,Java,Java 14,考虑以下代码: public class Example { @SneakyThrows private static VarHandle init() { MethodHandles.Lookup lookup = MethodHandles.lookup(); return lookup.findStaticVarHandle(Example.class, "x", int.class); } private final static
public class Example {
@SneakyThrows
private static VarHandle init() {
MethodHandles.Lookup lookup = MethodHandles.lookup();
return lookup.findStaticVarHandle(Example.class, "x", int.class);
}
private final static VarHandle X = init();
private static int x;
public static void main(String[] args) throws Exception {
Thread thread = new Thread(() -> {
System.out.println("Gonna wait till x becomes 1");
while ((int) X.get() != 1) ;
System.out.println("x is now 1");
});
thread.start();
new Thread(() -> {
// System.out.println("Sleeping for 1 second");
// sleep(1000); // uncomment this statement to reproduce
X.set(1);
}).start();
thread.join();
}
@SneakyThrows
public static void sleep(long ms) {
Thread.sleep(ms);
}
}
当我取消注释sleep时(1000)代码>语句并重新编译以运行它,程序将永远循环。现在要解决这个问题,我可以使用Thread.onSpinWait()虽然((int)X.get()!=1)
但是我真的很想了解为什么程序首先要这样做
注意:@skillythrows
来自lombok,用于使代码易于阅读。它就像一个普通的try-catch块。所说的“永远停止”是指“永远循环”?X.get()
没有任何订购授权人。JIT很可能会将代码重写为int\uu tmp=x;而(uu tmp!=1)代码>,永远循环。使用X.getOpaque()
。我承认我从来没有接触过VarHandle
s,但是一般来说,如果你在处理一个跨线程变量,你需要一个volatile变量。。。恰好VarHandle
s有.getVolatile
和.setVolatile
方法来复制这种行为。这取决于具体的用例。如果您想等待其他线程生成某些内容,.setRelease()
和.getAquire()
就足够了。@Powerlord为了安全起见。否则,一些维护人员可能会搞乱语义。无论如何,Johannes在订购方面是对的。你说的“永远停止”是指“永远循环”?X.get()
没有任何订购授权人。JIT很可能会将代码重写为int\uu tmp=x;而(uu tmp!=1)代码>,永远循环。使用X.getOpaque()
。我承认我从来没有接触过VarHandle
s,但是一般来说,如果你在处理一个跨线程变量,你需要一个volatile变量。。。恰好VarHandle
s有.getVolatile
和.setVolatile
方法来复制这种行为。这取决于具体的用例。如果您想等待其他线程生成某些内容,.setRelease()
和.getAquire()
就足够了。@Powerlord为了安全起见。否则,一些维护人员可能会搞乱语义。不管怎么说,约翰内斯的订货是对的。