静态初始化代码块启动新线程执行初始化

package example;

 
class Demo{
static {  
    //创建匿名内部类来启动新线程
    Thread t = new Thread() {  
        public void run() {  
            System.out.println("进入run方法");  
            System.out.println("------" + website);  
            website = "www.leegang.org";  
            System.out.println("++++++" + website);  
            System.out.println("退出run方法");  
        }  
    };  
    t.start();  
    try {  
        //加入t线程
        t.join();  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  
}  
//定义一个静态field
static String website = "www.crazyit.org";  

public static void main(String args[]) {  
    System.out.println("main:" + Demo.website);  
}  
}

奇怪的是只输出了进入run方法,并且在等待停止。

分析:

1,main线程试图访问Demo.website值,此时website尚未被初始化,因此main线程开始对该类执行初始化,步骤

    (1)为该类所有静态field分配内存

    (2)调用静态初始化块的代码执行初始化

2,main线程为Demo类的website field分配内存空间,值为null

3,main线程执行静态初始化块,创建一个新线程,并调用了join()方法,这说明main线程必须要等待新线程结束才能运行。

4,新线程打印"进入run方法",并试图运行System.out.println("------" + website);这时用到了website,但website正在main线程中初始化,

因为新线程会等待main线程对Demo类初始化结束。

5.两个线程 相互等待,形成死锁

下面去掉join()方法,查看结果

package example;

 
class Demo{
static {  
    //创建匿名内部类来启动新线程
    Thread t = new Thread() {  
        public void run() {  
            System.out.println("进入run方法");  
            System.out.println("------" + website);  
            website = "www.leegang.org";  
            System.out.println("++++++" + website);  
            System.out.println("退出run方法");  
        }  
    };  
    t.start();  
    /*try {  
        //加入t线程
        t.join();  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  */
}  
//定义一个静态field
static String website = "www.crazyit.org";  

public static void main(String args[]) {  
    System.out.println("main:" + Demo.website);  
}  
}

main:www.crazyit.org
进入run方法
------www.crazyit.org
++++++www.leegang.org
退出run方法

此时,main线程不会等待新线程结束,接着往下初始化,static String website = "www.crazyit.org"并打印,

接着之后再去新线程代码。(调用一条线程的start方法后,该线程不会立即进入运行状态,只是保持在就绪状态)。

在调用新线程时,让主线程暂停一下。

package example;

 
class Demo{
static {  
    //创建匿名内部类来启动新线程
    Thread t = new Thread() {  
        public void run() {  
            System.out.println("进入run方法");  
            System.out.println("------" + website);  
            website = "www.leegang.org";  
            System.out.println("++++++" + website);  
            System.out.println("退出run方法");  
        }  
    };  
    t.start();  
    try {  
        
        Thread.sleep(1);  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  
}  
//定义一个静态field
static String website = "www.crazyit.org";  

public static void main(String args[]) {  
    System.out.println("main:" + Demo.website);  
}  
}

进入run方法
------www.crazyit.org
main:www.crazyit.org
++++++www.leegang.org
退出run方法

主线程暂停时,进行新线程执行代码,打印进入run方法之后, 执行System.out.println("------" + website);,

但由于还没有初始化完成,所以会切换会main线程进行初始化website后,再去执行新线程。

静态初始化启动的新线程赋值不是初始化操作,只是一次普通的赋直,如下代码编译失败。

package example;

 
class Demo{
    
static {  
    //创建匿名内部类来启动新线程
    Thread t = new Thread() {  
        public void run() {  
        // website = "www.abc.org";  
        }  
    };  
    t.start();  
    try {  
        
        Thread.sleep(1);  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  
}  

    //final static String website ;  编译失败

public static void main(String args[]) {  
    
}  
}
原文地址:https://www.cnblogs.com/xurui1995/p/5346541.html