对象发布和初始化时的线程安全问题

如何理解逸出?

  • 方法返回一个private对象
  • 还未完成初始化,构造函数还没完全执行完毕,就把对象提供给外界 如 :
  • 在构造函数中未初始化完毕就this赋值
  • 隐式逸出 --- 注册监听事件
  • 构造函数中运行线程
我们来看方法返回一个private对象的这种情况:
public class UnsafeStates {
    private String[] states = new String( ) {
        "AK", "AL" ...
    };
    public String[] getStates() {
       return states;
    }
}

如果按照上述方式来发布states,就会出现问题。因为任何调用者都能修改这个数组的内容。在这个示例中,数组states已经逸出了它所在的作用越,因为这个本应是私有的变量已经被发布了,作用越以外的任何地方都可以修改其内容。因此它存在安全隐患。

我们来看在构造函数中未初始化完毕就this赋值的这种情况
public class ThisEscape {

    static Point point;

    public static void main(String[] args) throws InterruptedException {
        new PointMaker().start();
        Thread.sleep(10000);
        // Thread.sleep(105);
        if (point != null) {
            System.out.println(point);
        }
    }
}

class Point {

    private final int x, y;

    public Point(int x, int y) throws InterruptedException {
        this.x = x;
        ThisEscape.point = this;
        Thread.sleep(100);
        this.y = y;
    }

    @Override
    public String toString() {
        return x + "," + y;
    }
}


class PointMaker extends Thread {

    @Override
    public void run() {
        try {
            new Point(1, 1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

通过执行以上代码,我们会发现,不同时间段的请求,执行结果并非一致。在ThisEscape中给出了逸出的一个特殊示例,既this引用在构造函数中逸出。当从对象的构造函数中发布对象时,只是发布了一个尚未构造完成的对象。如果this引用在构造过程中逸出,那么这种对象就被认为是不正确构造。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容