繁体   English   中英

没有Thread.sleep(...)调用,线程代码无法正常工作

[英]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()方法。

另请注意:

  • Java命名约定:变量和方法名称应以小写字母开头( thrCountthrCountIncr()
  • sleep是一个静态方法,所以你可以简单地调用Thread.sleep(...); 它将在当前线程中休眠。

如果您的线程没有休眠,其他线程可能无法工作,因此ThrCountIncr内的循环可能随时被卡住(可能是在第一次sleep或在println )。

在没有任何睡眠或等待的情况下,永远不要让线程循环。

另请注意ThrCount++; 如果您不使用同步保护它可能会失败,因为它不是原子操作。

当循环迭代次数超过10,000次时,可以通过JIT进行优化。 在第二个线程的情况下,线程的代码不会修改字段,因此JIT可以优化if条件或确定它始终运行。

如果使字段volatile则会阻止JIT进行此类优化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM