Jive代码中AuthorizationFactory类

08-05-31 itworker
昨天看jive源码的时候,看到AuthoricationFactory这个类,觉得其中有一个方法实现得很巧妙。如下:

......
private static String className =
        "com.jivesoftware.forum.database.DbAuthorizationFactory";
private static void loadAuthorizationFactory() {
        if (factory == null) {
            //Use className as a convenient object to get a lock on.
            synchronized(className) {
                if (factory == null) {
                    //See if the classname has been set as a Jive property.
                    String classNameProp = JiveGlobals.getJiveProperty(
                            "AuthorizationFactory.className");
                    if (classNameProp != null) {
                        className = classNameProp;
                    }
                    try {
                        Class c = Class.forName(className);
                        factory = (AuthorizationFactory)c.newInstance();
                    }
                    catch (Exception e) {
                        System.err.println("Exception loading class: " + e);
                        e.printStackTrace();
                    }
                }
            }
        }
    }
......
<p class="indent">

将sychronized(className)将className这个变量上锁,防止了多个线程并发执行时其他线程对className进行写操作。例如,假如不上锁,线程一执行完className=classNameProp时,线程二执行了
className ="com.jivesoftware.forum.database.DbAuthorizationFactory";那么便可能改变了clasName的值。而且将factory==null放在synchronized(className)的外层,可以省下不少开销。
问题一、这里的为什么要使用单例模式?是为了只产生一个该类的实现类的实例而节省内存?
问题二、这里的单例模式也有些奇怪,既然将className都上锁了,为什么还要在内部再加一个
if(factory == nullll)?
问题三、这里的工厂中取得子类是通过持有自身的引用(当然引用所指的对象是它的子类)。那么,这种方式和直接在类里写一个方法: public static AuthorizationFactory getInstance(){......},再通过此方法给该类的AuthorizationFactory引用返回具体实例相比有什么区别与优势呢?

banq
2008-06-02 10:54
这是一个双lock的单例模式,这里单例是为了保证单线程。
现在这种单例方式已经过时,不在使用。

lyn
2008-06-03 22:37
在多核下,还是有问题!

oojdon
2008-06-22 16:33
加双锁在java中不是说不适用吗?那jive的代码有问题?
不适用原因是:java编译器本身的优化工作在构造方法实例化对象之前从构造方法返回指向对象的引用。
还是老老实实用框架吧,让高手门解决容器,组件,组件管理,线程等之类之类的问题。