Java线程问题(有没有大神解释下,为什么下面代码是个死循环)

public class ThreadDemo {

private static boolean stopRequested;

public static void main(String args[]) throws InterruptedException {

    Thread backageThread = new Thread(new Runnable() {
        @Override
        public void run() {
            int i = 0;
            while (!stopRequested)
                i++;
        }
    });

    backageThread.start();
    TimeUnit.SECONDS.sleep(1);
    stopRequested = true;

}

}

因为是while啊
你换成for试试

private static boolean stopRequested;

小布尔默认false,所以while处一直是true

一直在while,没有出来,执行不到stopRequested = true;这一句

boolean类型的初始值为false ,所以在while循环里面是出不来的,
无法执行到 TimeUnit.SECONDS.sleep(1); stopRequested = true;
你自己可以debugge 测一下

backageThread.start();执行到这一句的时候会启动线程调用线程中的run()方法;此时stopRequested = true;没有执行到,布尔的默认值是false;所以是死循环了;

TimeUnit.SECONDS.sleep(1);
stopRequested = true;
说这两句没有执行的我也很费解,调用Thread 的start()方法后,循环是在另一个线程中执行的呀,为啥当前线程的后面两句会执行不到

你设置值布尔值在生命的时候直接设置就好了,反正都是private static

已经测试,不会死循环
public class Test1 {
private static boolean stopRequested;
public static void main(String args[]) throws InterruptedException {
Thread backageThread = new Thread(new Runnable() {
@Override
public void run() {
int i = 0;
while (!stopRequested){
i++;
System.out.println(i);
}
}
});

    backageThread.start();
    System.out.println("--backageThread-----");
    TimeUnit.SECONDS.sleep(5);
    stopRequested = true;
    System.out.println("---stopRequested----");

// 输出:
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
// 10
// 11
// 12
// 13
// 14
// 15
// 16
// 17
// 18
// 19
// 20
// 21
// --backageThread-----
// 22
// ---stopRequested----

}

}

测试了下,循环里只有i++这样就不会退出,像下面这样
while (!stopRequested){
i++;
}

但把i++替换为别的,或者加个语句就可以退出了
while (!stopRequested){
System.out.println("looper i:"+i+" stopRequested:"+stopRequested);
}

很怀疑是不是因为i是个无意义的变量,编译器在编译的时候把它优化了

stopRequested加上volatile,则该循环会马上终止,如果没有,则改循环还真不一定会终止
stopRequested = true;一定会运行到,但多线程下,另一个线程什么时候收到stopRequested被改变了,则是不定的

线程A修改stopRequested = true,线程B检测到数据有变动去内存中拷贝数据到本地
线程A有可能还没来得及将stopRequested = true的数据从高速缓存(work memory)写入主存,线程B就从主存中取了stopRequested的数据,所以还有可能是0,这样就发生了数据错误!

应该是指令从排问题

不可能死循环不出来,这个也跟指令重排没关系,父线sleep是静态方法,线程暂停不会释放锁,jvm不会进行句柄顺序调优,因此代码还是会按照逻辑顺序执行,你将时间设置短一点,或者最后输出任意字符到控制台就看出来了