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

时间:2012-11-13 16:42:55

标签: java multithreading

我有以下代码:

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会使此代码生效?

3 个答案:

答案 0 :(得分:11)

即使使用Thread.sleep(),它也可能不起作用。这是因为您没有正确地同步对共享ThrCount变量的访问。

如果您创建该变量volatile,则不应再看到任何问题。但是,由于++操作不是原子操作,它可能不会完全循环10次。

理想情况下,您应该使用AtomicInteger并使用其incrementAndGet()方法。

另请注意:

  • Java命名约定:变量和方法名称应以小写字母开头(thrCountthrCountIncr()
  • sleep是一种静态方法,因此您只需调用Thread.sleep(...);即可在当前线程中休眠。

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:3)

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

如果您创建字段volatile,则会阻止JIT进行此类优化。