美文网首页Java并发
对象的发布与逸出

对象的发布与逸出

作者: 大海孤了岛 | 来源:发表于2017-04-11 07:35 被阅读149次
对象的发布

“发布对象”指的是使对象能够在当前作用于之外的代码中使用

例如,将一个指向该对象的引用保存到其他代码可以访问的地方(情况一),或者在某一个非私有的方法中返回该引用(情况二),或者将引用传递到其他类的方法中(情况三)。

//情况一
public class Person(){
    private String name;
    private int age;
}

public class Record{
    Person p;
}

//情况二
public class Person(){
    private String name;
    private int age;

    public Person get(){
        return new Person();
    }
}

//情况三
public class Person(){
    private String name;
    private int age;
}

public class Record{
    private void getPersonMessage(Person p){
        .....
    }
}
对象逸出

当某个不应该发布的对象被发布时,这种情况就被称为“对象逸出”。

常见的对象逸出:

  • 内部的可变状态逸出
class UnsafeStates{
    private String[] states = {"AK","AL",...};
    public String[] getStates(){
        return states;
    }
}

如上,数组states本事私有的变量,但是以public公有的方式发布出去,导致states已经逸出了它所在的作用域,任何调用者都能修改这个数组的内容。

  • 隐式地使this引用逸出
public class ThisEscape{
    public ThisEscape(EventSource source){
        source.registerListener(
            new EventListener(){
                public void onEvent(Event e){
                    dosomething(e);
                }
            })
    }
}

实际上,这里是需要发布内部类实例,而这样的做法导致当ThisEscape发布EventListener时,也隐含地发布了ThisEscape实例本身。因为在这个内部类的实例中包含了对ThisEscape实例的隐含引用。

这样的逸出会出现什么问题呢?

public class ThisEscape{
    private int count;
    public ThisEscape(EventSource source){
        source.registerListener(
            new EventListener(){
                public void onEvent(Event e){
                    dosomething(e);
                }
            })
        //在这里count初始化为1
        count = 1;
    }
}

举个例子,如上,我们知道this逸出会导致ThisEscape也发布出去,也就是ThisEscape还没有构建完成就发布出去,也就是count=1;这一句还没执行就发布了ThisEscape对象,如果要使用count时,很有可能会出现对象不一致的状态。

那么如何解决这个问题呢?
使用工厂方法来防止this引用在构造函数过程中逸出

public class SafeListener{
    private final EventListener listener;

    private SafeListener(){
        listener = new EventListener(){
            public void onEvent(Event e){
                dosomething(e);
            }
        };
    }

    public static SafeListener newInstance(EventSource source){
        SafeListener safe = new SafeListener();
        source.registerListener(safe.listener);
        return safe;
    }
}

如此,便能保证在对象为构造完成之前,是不会发布该对象。

相关文章

  • Java多线程之安全发布对象

    一、发布对象与对象逸出 发布对象:使一个对象能够被当前范围外的代码使用。 对象逸出:一种错误的发布,当对象没有构造...

  • 7 安全发布对象

    1️⃣发布与逸出 ① 概念 发布对象 : 使一个对象能够被当前范围之外的代码所使用;对象逸出 : 一种错误的发布,...

  • 对象的发布与逸出

    对象的发布 “发布对象”指的是使对象能够在当前作用于之外的代码中使用 例如,将一个指向该对象的引用保存到其他代码可...

  • 安全发布对象-发布与逸出

    发布对象 简单来说就是提供一个对象的引用给作用域之外的代码。比如return一个对象,或者作为参数传递到其他类的方...

  • 如何安全发布对象

    发布对象与逸出 发布对象: 使一个对象能够被当前范围之外的代码所使用,例如通过方法返回对象的引用,或者通过公有的静...

  • (并发二)保障线程安全的底层思路?

    先引入两个概念:发布和逸出 解释:     1.发布:使对象可以在当前作用域外使用     2. 逸出:发布了不该...

  • 11.对象的安全发布

    发布与逸出 发布一个对象的意思是,使对象能够在当前的作用域之外的代码中使用。例如将指向对象的引用保存到其他代码可以...

  • Java并发编程——"this"逸出解决方法的思考

    最近在看《Java并发编程实战》这本书的“3.2 发布与逸出”章节时,对“this”引用在对象构造方法中逸出问题的...

  • 1_基础知识_chapter03_对象的共享_2_发布与逸出

    发布: 使一个对象能够在当前作用域之外的代码中使用逸出: 某个不应该发布的对象被发布 (1) 发布对象最简单的方式...

  • 安全发布对象

    发布对象 发布对象:使一个对象能够被当前范围之外的代码所使用 对象逸出:一种错误的发布。当一个对象还没有构造完成时...

网友评论

    本文标题:对象的发布与逸出

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