public class NoVisibility {
  private static boolean ready=false;
private static int number;

private static class ReaderThread extends Thread {
public ReaderThread() {
System.out.println("Thread is created");
} public void run() {
int i=0;
while(!ready) {
i++;
Thread.yield();
System.out.println(number);
if(i==9) break;
}
}
}

public static void main(String[] args) {
ReaderThread s=new ReaderThread();
s.start();
System.out.println("main output context");
number = 42;
ready = true;
}


}为什么如上代码的运行结果总是:
Thread is created
main output context
而不是我想要的:
Thread is created
1
2
3
4
5
6
7
8
9
main output context

解决方案 »

  1.   

    main方法也是一个线程,而你的RUN方法调用了Thread.yield(); 
    所以main永远会优先执行.
      

  2.   

    public   class   NoVisibility   { 
      private   static   boolean   ready=false; 
    private   static   int   number; private   static   class   ReaderThread   extends   Thread   { 
    public   ReaderThread()   { 
    System.out.println("Thread   is   created"); 
    } public   void   run()   { 
    int   i=0; 
    while(ready)   { 
    i++;
    number=i; 
    Thread.yield(); 
    System.out.println(number); if(i==9)   break; 


    } public   static   void   main(String[]   args)   { 
    ReaderThread   s=new   ReaderThread(); 
    s.start(); 
    System.out.println("main   output   context"); 
    number   =   42; 
    ready   =   true; 

    } 把while(!ready)改为while(ready)
      

  3.   

    在运行ReaderThread时 main主线程多半已经运行到了ready   =   true; 
    这样就不可能进入while循环了
    System.out.println(number); 输出不是0就是42也不可能是1-9
    public class Test {
    private static boolean ready = false; private static int number; private static class ReaderThread extends Thread {
    public ReaderThread() {
    System.out.println("Thread   is   created");
    } public void run() {
    int i = 0;
    while (!ready) {
    i++;
    Thread.yield();
    System.out.println(i);
    if (i == 9)
    break;
    }
    }
    } public static void main(String[] args) {
    ReaderThread s = new ReaderThread();
    s.start();
    try {
    Thread.sleep(1000);
    }
    catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    System.out.println("main   output   context");
    number = 42;
    ready = true;
    }}
      

  4.   

    同意1楼的说法
    或者和我在2楼做一样的更改或者把main()方法里的ready = true;  注释掉因为main()优先执行,所以当运行RUN方法时的ready实际为true而不是初始化值的false
      

  5.   

    各位楼上的,第一肯定不是Thread.yield()影响的,第二,我问的是为什么?不是程序能否正确运行,谢谢
      

  6.   

    Thread.yield()会让出一小段时间让其他线程执行.
    在这个时候MAIN方法的
    System.out.println("main   output   context"); 
    number   =   42; 
    ready   =   true; 
    执行了.
    从此以后while(!ready)永远也进不去了,因为ready   =   true,明白没?
      

  7.   

    1.lz的程序不可能得到 1 2 3 ...这样的效果 System.out.println(number);
      注意这里print的是number 只可能是0或者42
    2.lz的程序里,main函数优先执行,number = 42;ready = true; 然后才执行的ReaderThread.run()。
    3.前面已经有人提出了方案 Thread.sleep(1000);就是要main等待一下,此时会执行run();
      

  8.   

    另外 lz的程序即使去掉Thread.yield() 仍然会继续执行完main 然后才run()
      

  9.   

    应该是main线程执行的速度很快吧,照6楼的说,是"Thread.yield()会让出一小段时间让其他线程执行. ",但实际上把Thread.yield()删掉以后,仍然得不出楼主想要的结果。
      

  10.   

    Thread.yield();   
    去掉就好了,如果你只是希望它执行的慢一点,用sleep
      

  11.   

    yield()只能把时间“让出来”,原理是:把当前占用的时间放开给别人。但是谁也不能保证是不是CPU又把时间分给他,他还会占用时间的,那这样跟没yield()之前有一样了……所以线程的优先不能用延迟,这个方法逻辑可能不是很完备。可以试试用下边的方法:suspend() 阻塞线程——之后线程不再分到CPU时间
    resume() 放开阻塞——之后线程又可以分到CPU时间了