快速业务通道

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

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-19
ass EventListener2 {   public EventListener2(EventSource eventSource) {    eventSource.registerListener(     new EventListener() {   public onEvent(Event e) {       eventReceived(e);      }     });   }   public onEvent(Event e) {   } }

EventListener2 类和其类似代码 清单 2 中的 EventListener 有同样的弊端:公布了对正在构造的对象的引用 ― 在这种情况下,是间接的 ― 另一个线程可以看见这个引用。如果打算创建 EventListener2 的子类,将会碰到同样的问题,即在子类构造函数完成之前会调用子类方法。

不要从构造函数内启动线程

清单 4 问题的一个特例是,从构造函数内启动了一个线程,由于当一个对象拥有一个线程时,通常这个线程要么是一个内部类,要么我们将 this 引用传递给其构造函数(或者该类本身继承了 Thread 类)。如果一个对象将拥有一个线程,那么,如果对象如 Thread 那样提供一个 start() 方法,并从 start() 方法而不是从构造函数启动线程,那是最好的。虽然通过接口,这会暴露类的一些实现细节(譬如,可能存在拥有一个线程),这往往是我们不期望的,但在这种情况下,从构造函数启动线程的害处要比隐藏实现所带来的好处多。

“公布”是指什么?

在构造期间,不是所有对 this 引用的引用都是有害的,只有那些公布引用,使其它线程看到该引用的引用才是有害的。确定与其它对象共享 this 引用是否安全,需要详细了解对象的可见性以及对象将如何利用引用。关于让 this 引用在构造期间逃脱,清单 5 列出了一些安全和不安全做法的示例:

清单 5. 在构造期间,安全和不安全地使用“this”引用

public class Safe {   private Object me;   private Set set = new HashSet();   private Thread thread;    public void run() {    // Safe because "me" is not visible from any other thread    me = this;    // Safe because "set" is not visible from any other thread    set.add(this);    // Safe because MyThread won''t start until construction is complete    // and the constructor doesn''t publish the reference    thread = new MyThread(this);   }    public void run() {    thread.start();   }   private class MyThread(Object o) {    private Object theObject;    public MyThread(Object o) {     this.theObject = o;    }    ...   } } public class Unsafe {   public static Unsafe anInstance;   public static Set set = new HashSet();   private Set mySet = new HashSet();    public void run() {    // Unsafe because anInstance is globally visible    anInstance = this;    // Unsafe because SomeOtherClass.anInstance is globally visible    SomeOtherClass.anInstance = this;    // Unsafe because SomeOtherClass might save the "this" reference    // where another thread could see it    SomeOtherClass.registerObject(this);    // Unsafe because set is globally visible    set.add(this);    // Unsafe because we are publishing a reference to mySet    mySet.add(this);    SomeOtherClass.someMethod(mySet);    // Unsafe because the "this" object will be visible from the new    // thread before the constructor completes    thread = new MyThread(this);    thread.start();   }    public void run() {    // Unsafe because &quo

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号