public class T {
static volatile boolean done = false;
static {
new Thread() {
public void run() {
System.out.println("enter thread");
done = true;
}
}.start();
while (! done)
;
} public static void main(String[] args) {
System.out.println("Finished");
}
}

解决方案 »

  1.   

    先执行静态块嘛.输出enter thread
    但是其中有点不定因素.sart()不一定马上就启动那个线程吧.main()方法是另一个线程吗?我感觉是enter thread然后Finished.
      

  2.   

    while (! done)
                ;
    难是这个先执行.然后一直锁住了done 
      

  3.   

        while (! done)
                ;
    这个是死循环。
      

  4.   

    虽然知道结果,但是对class loader这个东西还是比较不懂
      

  5.   


    try{
    Thread.sleep(10000);
    while (! done)
    ;
    }catch(InterruptedException e){

    }这样呢?
      

  6.   

    加入了其他标志等,跑了一下……
    发现new Thread()中的那个赋值语句始终在静态模块中的其他过程都完成之后执行……
    其他的顺序具有不确定性
      

  7.   

    也就是说,线程要访问静态变量,起码要等静态域初始化完成之后才可以访问。
    而while循环算是静态模块初始化过程。
      

  8.   

    http://www.java2000.net/viewthread.jsp?tid=2672
    运行结果:enter thread 这个小程序不会终止。其主线程会陷入死循环,那个单独的线程会永远等待。为方便起见,称主线程为M,单独的线程为N。代码的执行过程大体如下: 1. M看到类Init, 获取Init.class上的锁,判断初始化是否正在进行,或着已完成。 2. 此时初始化既未进行,也未完成,于是M设一个标志表示初始化正在进行,然后释放Init.class上的锁 3. M开始初始化类Init, 完成对Init.done的初始化 4. M进入static块,启动N, 进入while循环 5. N开始运行,打印出"enter thread", 6. N看到Init.done, 这是N第一次看到类Init, 所以像M一样,试图初始化Init。 7. 与步骤1类似,N 成功获取Init.class上的锁 8. N发现M所设的初始化正在进行的标志,N就释放Init.class的锁,并进入等待状态。 9. 由于N在等待,Init.done一直为false,M就一直在while中循环,不能退出static块. 10. 由于M对Init的初始化不能完成,所以N不能得到M的通知而退出等待。 可见,这是一个M和N的死锁问题。 一般而言,只要N引用类本身或类的成员,包括任何method或field,N都会先去初始化这个类从而陷入死锁。 但是有例外,例如如果N引用的是一个常变量(constant variable),N 就不会去初始化这个类,例如如果Init有以下成员,  引用它就可以。 final boolean ok = false; 还有一个例外,以下语句出现在run()中也不会引发Init的初始化. Init C = null; 
      

  9.   

                while (! done)
                {
                    System.out.println("done");
                    break;
                }强!! 
    学习ing!
      

  10.   

    上面将Init 全部替换为T
    运行结果:enter thread  这个小程序不会终止。其主线程会陷入死循环,那个单独的线程会永远等待。为方便起见,称主线程为M,单独的线程为N。代码的执行过程大体如下:  1. M看到类T, 获取T.class上的锁,判断初始化是否正在进行,或着已完成。  2. 此时初始化既未进行,也未完成,于是M设一个标志表示初始化正在进行,然后释放T.class上的锁  3. M开始初始化类T, 完成对T.done的初始化  4. M进入static块,启动N, 进入while循环  5. N开始运行,打印出"enter thread",  6. N看到T.done, 这是N第一次看到类T, 所以像M一样,试图初始化T。  7. 与步骤1类似,N 成功获取T.class上的锁  8. N发现M所设的初始化正在进行的标志,N就释放T.class的锁,并进入等待状态。  9. 由于N在等待,T.done一直为false,M就一直在while中循环,不能退出static块.  10. 由于M对T的初始化不能完成,所以N不能得到M的通知而退出等待。  可见,这是一个M和N的死锁问题。  一般而言,只要N引用类本身或类的成员,包括任何method或field,N都会先去初始化这个类从而陷入死锁。  但是有例外,例如如果N引用的是一个常变量(constant variable),N 就不会去初始化这个类,例如如果T有以下成员,  引用它就可以。  final boolean ok = false;  还有一个例外,以下语句出现在run()中也不会引发T的初始化.  T c = null;  
      

  11.   

    try{ 
                Thread.sleep(10000); 
                while (! done) 
                    ; 
            }catch(InterruptedException e){ 
                 
            } 
    加个捕获异常 还不是样  处于等待状态
      

  12.   

    是初始化吗,还是程序执行过程中,对同意个变量访问,引发对done的同时访问,其中操作系统对程序对done访问时候加锁,其他的线程不能够再访问,导致了其他进程的等待.
      

  13.   

    static volatile boolean done = false;关注一下 这个里面的 volatile , 感觉是它引起的。volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,
    比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
      

  14.   

    运行结果:enter thread
    死循环
    关键由于Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
      

  15.   

    同时java中允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
      

  16.   

    但是而volatile关键字指出了对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
      

  17.   

    居然会当机?
    按说线程早晚会执行完的,那时done就是true了,while应该结束才对呀