快速业务通道

Java理论和实践: 安全构造技术 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-19
细信息。

Java理论和实践: 安全构造技术(2)

时间:2011-02-04 Brian Goetz

在构造期间,不要公布“this”引用

一种可以将数据争用引入类中的错误是,在构造函数完成之前,使 this 引用暴露给另一个线程。有时这个引用是显式的,(譬如,直接将 this 存储在静态字段或集合),但还有一些时候它可以是隐式的(譬如,当将一个引用公布给构造函数中的非静态内部类的实例时)。构造函数不是一般的方法 ― 它们有特殊的用于初始化安全的语义。在构造函数完成之后,可以认为对象是处于一种可预测和一致的状态,将引用公布给一个还未完成构造的对象是危险的。清单 2 显示了将这类争用条件引入构造函数的示例。这个示例看上去可能没有危害性,但它可以引发严重的并发性问题。

清单 2. 可能发生的数据争用

public class EventListener {   public EventListener(EventSource eventSource) {    // do our initialization    ...    // register ourselves with the event source    eventSource.registerListener(this);   }   public onEvent(Event e) {    // handle the event   } }

乍一看, EventListener 类似乎没有危害性。构造函数最后完成的工作是注册侦听器,这会将引用公布给新对象,这时其它线程可能会看到这个引用。但即使不考虑所有 Java 内存模型(JMM)问题(譬如,多个线程所看见同一数据的不一致性以及内存访问重排序的不同),该代码仍然有将还未完成构造的 EventListener 对象暴露给其它线程的危险。考虑清单 3 中这种情况,当创建 EventListener 的一个子类时,会发生什么:

清单 3. 创建 EventListener 的一个子类时,问题产生了

public class RecordingEventListener extends EventListener {   private final ArrayList list;   public RecordingEventListener(EventSource eventSource) {    super(eventSource);    list = Collections.synchronizedList(new ArrayList());   }   public onEvent(Event e) {    list.add(e);    super.onEvent(e);   }   public Event[] getEvents() {    return (Event[]) list.toArray(new Event[0]);   } }

由于 Java 语言规范要求对 super() 的调用应该是子类构造函数中的第一条语句,所以在完成子类字段的初始化之前,还未构造完的事件侦听器已经对事件源进行了注册。现在, list 字段存在数据争用。如果事件侦听器决定从注册调用内发送一个事件,或者我们很不幸,在这不恰当的时刻,一个事件到来了,则会调用 RecordingEventListener.onEvent() ,而这时 list 仍然是 null 值,结果会抛出 NullPointerException 异常。就象 onEvent() 这样的类方法一样,在编码时,应该避免使用还未初始化完的 final 字段。

清单 2 中的问题在于, EventListener 在构造完成之前会向正在构造的对象公布一个引用。虽然看上去 几乎已经完整地构造了对象,所以将 this 传递给事件源好象是安全的,但这种表像是具有欺骗性的。公布来自构造函数内的 this 引用(如清单 2 所示)就象放置了一颗随时会爆炸的定时炸弹。

Java理论和实践: 安全构造技术(3)

时间:2011-02-04 Brian Goetz

不要隐式地暴露“this”引用

在根本不使用 this 引用情况下,也有可能会造成逃脱的引用问题。非静态内部类维护着其父类的 this 引用的隐式副本,所以创建匿名的内部类实例,并将其传递给从当前线程外部可以看见的对象,会存在与暴露 this 引用本身所具有的所有相同的风险。考虑清单 4,它与清单 2 有同样的根本问题,但这里没有显式地使用 this 引用:

清单 4. 使用匿名内部类时,不正确地公布了“this”

public cl

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号