美文网首页
对象发布和初始化时的线程安全问题

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

作者: AD刘涛 | 来源:发表于2020-11-01 09:36 被阅读0次

    如何理解逸出?

    • 方法返回一个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引用在构造过程中逸出,那么这种对象就被认为是不正确构造。

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/brhyvktx.html