this指针逃逸问题
this指针逃逸是指在构造函数返回之前,其他线程已经就持有了该对象的应用,产生的结果自然和预期可能会产生差异。
常见的this指针逃逸,在并发编程实战一书中,作者指出:在构造函数中注册事件监听,在构造函数中启动新线程。
由于注册事件,并没有用过,因此以线程为例说明问题。:
public class TestEscape { private String name; public TestEscape(String name) throws InterruptedException { new Thread(new EscapeRunnable()).start(); // Thread.sleep(1); //增加构造函数的负责度,加长name初始化时间,否则在测试过程中,并没有发生其为null的情况 this.name = name; } private class EscapeRunnable implements Runnable { @Override public void run() { System.out.println(name); } } public static void main(String[] args) throws InterruptedException { new TestEscape("woniu"); } }
解决办法是,不在线程中启动线程或者注册事件,将线程的启动在初始化完成后,再次进行启动。
public class TestEscape { private String name; private Thread thread; public TestEscape(String name) throws InterruptedException { thread = new Thread(new EscapeRunnable()); Thread.sleep(1); //增加构造函数的负责度,加长name初始化时间,否则在测试过程中,并没有发生其为null的情况 this.name = name; } public void init() { thread.start(); } private class EscapeRunnable implements Runnable { @Override public void run() { System.out.println(name); } } public static void main(String[] args) throws InterruptedException { //由于已经将构造函数初始化完成,其后调用的方法,均可以正常执行,与预期无差异。 new TestEscape("woniu").init(); } }