为什么打印输出全是0,而第二种情况输出是42

package com.my.current;

public class NoVisibility {

private static  volatile boolean ready;
private static   int number;
private static class ReaderThread extends Thread{
    public void run(){
        while(!ready){

            System.out.println(number);
        }
        //while(!ready);
        //System.out.println(number);
    }
}

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

    new ReaderThread().start();
    Thread.sleep(1000);
    number = 42;
    ready = true;
    Thread.sleep(1000);
}

}

 第一个是
while(!ready)
{
System.out.println(number);
}
第二个相当于
while(!ready)
{
}
System.out.println(number);

一个是ready以前输出,一个是以后输出。

开始number还没有修改值,后来修改了,ready变了,循环退出了,也不会打印了

其实也不一定一直是0,这个还是主线程与子线程运行之间的一个时间差的原因。你在main方法中也加一个死循环,可以观察一下结果。
new ReaderThread().start();
while(true){
ready=false;
Thread.sleep(1000);
number = 42;
ready = true;
Thread.sleep(1000);
}

只有一个线程,一个全局变量,你还想搞出多线程同步互斥的效果?

main 也是个线程,应该优先级默认比你创建的线程可能还要快。如果ready被修改为true,你的另外一个线程就失去意义了,少的话一次也不会执行。
多的话也要看运气,最多竞争到一次就over了。如果你把自己创建的线程写成死循环。那样才公平竞争
package mine.dataValueFirst;
public class NoVisibility {
private static volatile boolean ready;
private static int number;
private static class ReaderThread extends Thread{
public void run(){
while(true){

        System.out.println("ReaderThread"+ready+":number"+number);
        while(!ready){
            System.out.println("ReaderThread"+ready+number);
        }
        //while(!ready);
        //System.out.println(number);
    }
}

}

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

new ReaderThread().start();
Thread.sleep(1000);
number = 42;
ready = true;
Thread.sleep(1000);
while(true){
    System.out.println("主线程"+ready+number);
}

}
}

//while(!ready);//这里有个分号,结束了while