静态初始化代码块启动新线程执行初始化
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[]) { } }
相关文章推荐
- 27 API-反射(类的加载器,反射的使用,动态代理)&设计模式(装饰设计模式,模版设计模式)&JDK新特性(JDK5,JDK6,JDK7,DK8)
- 笔记:C语言文件处理
- Struts2中的Action
- 练习001-002
- 1002. 写出这个数 (20)
- Java集合类之栈Stack
- c_str()
- springmvc and maven
- 配置持久化框架diamond简介及高阶应用
- 配置持久化框架diamond简介及高阶应用
- Matlab中三维直方图的显示方法
- Java集合类之向量Vector
- Spring学习笔记(2)-Spring中bean的生命周期
- 小代码
- Django视图和网址
- LeetCode Algorithms #26 <Remove Duplicates from Sorted Array>
- Java集合类之LinkedList链表
- [译]学习IPython进行交互式计算和数据可视化(七)
- 一些特别有趣的C++面试题(持续更新中)
- 常用排序算法 Java 实现