美文网首页
安全发布对像

安全发布对像

作者: 三不猴子 | 来源:发表于2019-05-09 21:12 被阅读0次

发布对像

定义: 是一个对象能够被当前范围之外的代码所使用

对象溢出

一种错误的发布。当一个对象该没有构造完成时,就使被其他线程所见。

下面我们来看一下没有安全发布的对象

@Slf4j
public class UnsafePublish {

    private String[] states = {"a", "b", "c"};

    public String[] getStates() {
        return states;
    }

    public static void main(String[] args) {
        UnsafePublish unsafePublish = new UnsafePublish();
        log.info("{}", Arrays.toString(unsafePublish.getStates()));

        unsafePublish.getStates()[0] = "d";
        log.info("{}", Arrays.toString(unsafePublish.getStates()));
    }
}

我们看这段代码,我们创建了一个对象通过getStates方法我们可以获取这个对象的数组,此时我们将数组内容打印出来结果,如果此时我们将这个对象发布出去,然后其他线程(这里没有模拟其他线程对其修改)又对这个对象的states的值进行修改,此时在拿到这个对象的期望的是没有被修改的,事实上得到的对象是修改过后的。也就是说我们不能直接通过一个public的一个set方法就行return。

下面我们再看一段对象溢出的代码

public class ThisEscape {
  public ThisEscape(EventSource source) {
    source.registerListener(new EventListener() {
      public void onEvent(Event e) {
        doSomething(e);
      }
    });
  }
 
  void doSomething(Event e) {
  }
 
  interface EventSource {
    void registerListener(EventListener e);
  }
 
  interface EventListener {
    void onEvent(Event e);
  }
 
  interface Event {
  }
}

这将导致this逸出,所谓逸出,就是在不该发布的时候发布了一个引用。在这个例子里面,当我们实例化ThisEscape对象时,会调用source的registerListener方法,这时便启动了一个线程,而且这个线程持有了ThisEscape对象(调用了对象的doSomething方法),但此时ThisEscape对象却没有实例化完成(还没有返回一个引用),所以我们说,此时造成了一个this引用逸出,即还没有完成的实例化ThisEscape对象的动作,却已经暴露了对象的引用。其他线程访问还没有构造好的对象,可能会造成意料不到的问题。

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;
  }
 
  void doSomething(Event e) {
  }
 
  interface EventSource {
    void registerListener(EventListener e);
  }
 
  interface EventListener {
    void onEvent(Event e);
  }
 
  interface Event {
  }
}

在这个例子中我们使用匿名类的形式来构造,只有在整个对象都实例化好了才能会执行。只有当构造函数返回时,this引用才应该从线程中逸出。构造函数可以将this引用保存到某个地方,只要其他线程不会在构造函数完成之前使用它

相关文章

  • 安全发布对像

    发布对像 定义: 是一个对象能够被当前范围之外的代码所使用 对象溢出 一种错误的发布。当一个对象该没有构造完成时,...

  • Java高并发--安全发布对象

    Java高并发--安全发布对象 主要是学习慕课网实战视频《Java并发编程入门与高并发面试》的笔记 发布对像:使一...

  • 对像

    诗歌 看着你,我总是摇头苦叹 因为我得不到你的喜欢。 看着你,我总要闭起双眼 因为我在想着怎样对你亲昵的景象。 看...

  • iOS 对像

    1、对像 -概念:是提我们通常类的实例化对像。 -元类:就是类对像的 isa指像的类 打开#import

  • 类和对象的使用之对象指针

    在建立对像时,编译系统会为每一个对像分配一定的存储空间,以存放其成员,对像空间的起始地址就是对像的指针。可以定义一...

  • 怎么找对像

    刚看到一个故事关于满意决策。这也同苏格拉底的麦穗理论关于婚姻差不多一样。但这用到了数学,如果有兴趣的还可以去看一下...

  • 对像和类

    Java 对象和类 多态 继承 封装抽象 Java对象和类 类对象实例方法消息解析代码: 11 运行结果: 小狗的...

  • 5 安全发布

    不安全的发布 这种发布会导致其他线程看到尚未未构建完成的对象,另一个线程在调用assertSanity 方法可能会...

  • 安全发布对象

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

  • 安全发布对象

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

网友评论

      本文标题:安全发布对像

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