在阅读《java并发编程实战》的第三章的时候,看到书中的一个例子,随在Eclipse中执行看看效果。示例代码如下:

 

Java代码 多线程中共享对象的可见性 _的 多线程中共享对象的可见性 _多线程_02
  1. public class NoVisibility {
  2. private static boolean ready;
  3. private static int number;
  4.  
  5. private static class ReaderThread extends Thread {
  6. public void run() {
  7. while(!ready) {
  8. Thread.yield();
  9. }
  10.  
  11. System.out.println(number);
  12. }
  13. }
  14.  
  15. public static void main(String[] args) {
  16. new ReaderThread().start();
  17.  
  18. number = 42;
  19. ready = true;
  20. }
  21. }

 

 

书中的解释是,这个程序的执行结果除了打印出42以外,还有两外另种情况:一时无限循环下去,二是打印出0来。其中打印42很好理解,因为,在启动ReaderThread线程以后,如果还没有设置ready为true,那么ReaderThread会一直循环,直到读取ready的值为true,然后打印出结果42来。

 

无限循环这个结果,通过代码来测试是很难观察到的,但是通过书中的分析,这种情况是存在的。这个示例中的number和ready,会被两个线程访问,其一是运行该程序的main线程,其二是ReaderThread线程,所以这两个变量可以称之为共享变量,由于java虚拟机自己的缓存机制,在缺少同步的情况下,会将number和ready的数值缓存在寄存器中,这就会导致ReaderThread线程在某些情况下读取不到最新的值,这样即使在main方法中将ready设置为true了,但是ReaderThread线程读取的ready值仍然为false,这样就会导致一直循环下去。