您的位置:首页 > 编程语言

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

2016-04-01 21:59 337 查看
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[]) {

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: