[英]Thread code not work properly without Thread.sleep(…) call
我有以下代码:
public class ThreadTest implements Runnable {
public int ThrCount = 0;
public void ThrCountIncr() {
while (true) {
ThrCount++;
System.out.println(ThrCount);
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void run() {
while (true) {
if (ThrCount > 10) {
System.out.println(ThrCount + "\n Thread finished");
System.exit(1);
}
try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
但是当我从run
删除此行时,它将停止工作:
Thread.currentThread().sleep(100);
首先,我启动线程,然后我使用ThrCountIncr
。
ThreadTest Thrtest = new ThreadTest();
Thread thr = new Thread(Thrtest);
thr.start();
Thrtest.ThrCountIncr();
线程检查ThrCount
变量值,如果它大于10,则它会停止程序。 没有sleep(100)
,线程不会停止程序,我认为它不会检查变量值。 为什么sleep
调用使这段代码有效?
即使使用Thread.sleep()
它也可能不起作用。 这是因为您没有正确同步对共享ThrCount
变量的访问。
如果您将该变量设置为volatile
,则不应再看到任何问题。 但是,由于++
操作不是原子操作,它可能不会完全循环10次。
理想情况下,您应该使用AtomicInteger并使用其incrementAndGet()
方法。
另请注意:
thrCount
, thrCountIncr()
sleep
是一个静态方法,所以你可以简单地调用Thread.sleep(...);
它将在当前线程中休眠。 如果您的线程没有休眠,其他线程可能无法工作,因此ThrCountIncr
内的循环可能随时被卡住(可能是在第一次sleep
或在println
)。
在没有任何睡眠或等待的情况下,永远不要让线程循环。
另请注意ThrCount++;
如果您不使用同步保护它可能会失败,因为它不是原子操作。
当循环迭代次数超过10,000次时,可以通过JIT进行优化。 在第二个线程的情况下,线程的代码不会修改字段,因此JIT可以优化if
条件或确定它始终运行。
如果使字段volatile
则会阻止JIT进行此类优化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.