试验《Java并发编程实践》3.2的"不要让this在构造期间逸出"
import java.io.IOException;public class Demo { public Demo(T1 t1){ t1.demo = this;// 将this在构造期间就逸出,这样逸出的对象被认为是“没有正确构建的(not properly constructed)” try { Thread.sleep(100000000L); } catch (InterruptedException e) { e.printStackTrace(); } } public void print() { System.out.println("demo's method"); } public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException { T1 t1 = new T1(); t1.start(); new Demo(t1); } static class T1 extends Thread { public Demo demo; public void run() { while (true) { if (demo != null) {// 事实证明,即使Demo的构造方法未执行完,this赋值给T1.demo后,不为null demo.print();// 且能够正常使用demo的实例方法。至于由于demo的构造方法未执行完会带来什么不稳定的影响,应该是指它可能未按照预期的去初始化一些数据。 } try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } } } }}
?
?
实验表明:this在构造期间(未完成构造)可以逸出,并且看起来使用很正常,但使用“没有构造完全的对象”,会有隐患,这就是书里想说的道理。
?
?
上面的例子,讲述“逸出”的例子,但是它没有展现出“逸出”的危害。
下面将展示“逸出”的危害,它将final域的默认值给打印了出来。
?
import java.io.IOException;public class Demo { final int x; public Demo(T1 t1){ t1.demo = this;// 将this在构造期间就逸出,这样逸出的对象被认为是“没有正确构建的(not properly constructed)” try { Thread.sleep(100000000L); } catch (InterruptedException e) { e.printStackTrace(); } x=9; } public void print() { System.out.println(this.x); } public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException { T1 t1 = new T1(); t1.start(); new Demo(t1); } static class T1 extends Thread { public Demo demo; public void run() { while (true) { if (demo != null) { demo.print(); } try { Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } } } }}?
打印了:
0
0
0
0
0
....
?
?