Mycat源码中的单例模式

在MyCat的源码中,很多对象都使用到了单例模式。

首先是MycatServer类,该实例必须全局唯一,所以这里涉及到JAVA的单实例模式,就是一个类只有唯一一个实例对象存在。先来看看mycat源码是怎么做的:

public class MycatServer {
    private static final MycatServer INSTANCE = new MycatServer();
    
    public static final MycatServer getInstance() {
        return INSTANCE;
    }
 
    private MycatServer() {
        ......
    }
}
public final class MycatStartup {

    public static void main(String[] args) {
        MycatServer server = MycatServer.getInstance();
    }
    
}

首先,将构造方法定义成私有的,这样外界不能再实例化该类。然后,提供一个公有的静态方法,使外界只能通过该方法来获取类实例,该方法返回一个类型为类本身的静态属性值,该属性值在类加载时调用私有构造方法初始化。这就保障了,该类只有唯一一个实例对象的存在。

上面这种写法是单实例创建的饿汉模式,线程安全,但浪费内存空间,不过mycat要运行MycatServer类是肯定要装载的,所以源码里这样用也没有问题。

还有一种静态内部类单例实现方式,集所有优点于一身,推荐使用:

public class Singleton {
    private Singleton(){
        
    }
    private static class SingletonHolder{
        private final static Singleton instance=new Singleton();
    }
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

内部类不会随主类加载而加载,只有在第一次使用时才会加载,而单实例又是内部类的静态实例,所以用这种方式获取单实例,即是lazy loading,节省内存,又是线程安全且不需要同步锁的。所以用这种方式获取单实例最好。

参考文章:https://blog.csdn.net/john_chang11/article/details/78679867

另外,在Mycat的源码中有很多地方都使用到了饿汉式的单例模式,比如ZkConfig:

public class ZkConfig {
    private ZkConfig() {
    }
    
    private static ZkConfig ZKCFGINSTANCE = new ZkConfig();

    public  static ZkConfig getInstance() {
        return ZKCFGINSTANCE;
    }
    
    public void initZk(){
        //...
    }
}
public final class MycatStartup {
    public static void main(String[] args) {
        //use zk ?
        ZkConfig.getInstance().initZk();
    }
}

还有下面几个类:

public class TableStatAnalyzer implements QueryResultListener {
    private final static TableStatAnalyzer instance  = new TableStatAnalyzer();
    
    private TableStatAnalyzer() {}
    
    public static TableStatAnalyzer getInstance() {
        return instance;
    }
}
public class QueryConditionAnalyzer implements QueryResultListener {
 private final static QueryConditionAnalyzer instance  = new QueryConditionAnalyzer();
    
    private QueryConditionAnalyzer() {}
    
    public static QueryConditionAnalyzer getInstance() {
        return instance;
    }  
}

还有一个使用静态内部类实现单例的:

public class MyCATSequnceProcessor {

    private static class InnerMyCATSequnceProcessor{
        private static MyCATSequnceProcessor INSTANCE = new MyCATSequnceProcessor();
    }
    
    public static MyCATSequnceProcessor getInstance(){
        return InnerMyCATSequnceProcessor.INSTANCE;
    }
}
原文地址:https://www.cnblogs.com/jun1019/p/9626243.html