2 dzbkq 110 dzbkq_110 于 2017.04.21 22:35 提问

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

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);
}

}

6个回答

caozhy
caozhy   Ds   Rxr 2017.04.21 22:39
 第一个是
while(!ready)
{
System.out.println(number);
}
第二个相当于
while(!ready)
{
}
System.out.println(number);

一个是ready以前输出,一个是以后输出。
qq_31258403
qq_31258403   2017.04.21 23:38

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

qq_34108067
qq_34108067   2017.04.22 00:03

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

hongyu83916
hongyu83916   2017.04.22 00:09

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);
}

}
}

m0_37963240
m0_37963240   2017.04.22 15:51

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

oyljerry
oyljerry   Ds   Rxr 2017.04.21 22:42

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

Csdn user default icon
上传中...
上传图片
插入图片