JAVA 与 MyCat(2) 单例模式
来源:互联网 发布:数据库的设计原则答案 编辑:程序博客网 时间:2024/06/06 23:56
通过mycat来学习java了^^。
接前一篇:http://blog.csdn.net/john_chang11/article/details/78668667
MycatServer server = MycatServer.getInstance();
获取MyCat实例,其实就是读取配置文件,并验证正确性等。
MyCat实例必须全局唯一,所以这里涉及到JAVA的单实例模式,就是一个类只有唯一一个实例对象存在。先来看看mycat源码是怎么做的:
public class MycatServer {private static final MycatServer INSTANCE = new MycatServer();public static final MycatServer getInstance() {return INSTANCE;}private MycatServer() {......}}
首先,将构造方法定义成私有的,这样外界不能再实例化该类。然后,提供一个公有的静态方法,使外界只能通过该方法来获取类实例,该方法返回一个类型为类本身的静态属性值,该属性值在类加载时调用私有构造方法初始化。这就保障了,该类只有唯一一个实例对象的存在。
上面这种写法是单实例创建的饿汉模式,线程安全,但浪费内存空间,不过mycat要运行MycatServer类是肯定要装载的,所以源码里这样用也没有问题。单实例模式的写法还有别的写法,一起看看。
1.懒汉,省内存空间,但线程不安全,不推荐使用
public class Singleton { private static Singleton instance=null; private Singleton(){ } public static Singleton getInstance(){ if(instance==null){ instance=new Singleton(); } return instance; }}
使用时才初始化实例,所以省内存,但也影响了速度,而且线程不安全,只能在单线程环境下可行,不推荐使用。
2.懒汉,线程安全,但效率低,不推荐使用
public class Singleton { private static Singleton instance=null; private Singleton(){ } public static synchronized Singleton getInstance(){ if(instance==null){ instance=new Singleton(); } return instance; }}这种方式也是在使用时才初始化,省内存,但每次调用getInstance()方法时,都需要获取同步锁,非常耗时,也不推荐使用。
3.懒汉,双重检查锁,依然有问题,不推荐使用
public class Singleton { private static Singleton instance=null; private Singleton(){ } public static Singleton getInstance(){ if(instance==null){ synchronized(Singleton.class){ if(instance==null){ instance=new Singleton(); } } } return instance; }}这种方式是对第2种的改进,只在第一次创建实例时需要同步锁,以后不再需要,大大提高了性能。但是这种方式依然有问题,这与JAVA内存模式的无序写入有关,即使使用volatile,也依然有问题。为了不偏离主题,本文不详细介绍这些问题的原因,有兴趣可以参考:http://blog.csdn.net/chenchaofuck1/article/details/51702129和http://blog.csdn.net/axman/article/details/1089196
4.饿汉,线程安全,效率高,但内存使用率低,推荐使用
public class Singleton { private static Singleton instance=new Singleton(); private Singleton(){ } public static Singleton getInstance(){ return instance; }}这种方式,是利用JVM的机制:静态实例的初始化是ClassLoader经由[ThreadSafe]来完成,所以是线程安全的。该方法去除的同步,且类加载时就创建实例,所以效率高。但由于是类加载时就创建实例,所以内存使用率低,不过既然使用该类一般就会初始化该类的一个实例,所以该仍然推荐使用。
5.静态内部类,集所有优点于一身,推荐使用
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,节省内存,又是线程安全且不需要同步锁的。所以用这种方式获取单实例最好。不过,使用时才创建实例,会对第一次调用产生影响,所以这种方式与第4种方式,可以互补使用:如果单实例类一定需要初始化,就用第4种,如果不一定需要初始化,就用第5种。
阅读全文
0 0
- JAVA 与 MyCat(2) 单例模式
- Java与模式-单例模式(一)
- java与模式(1)单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》-单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》之单例模式
- 《java与模式》之单例模式
- 《JAVA与模式》之单例模式
- 《JAVA与模式》之单例模式
- 蓝桥杯练习题之 Fibonacci数列
- git 命令
- OOALV单个container放置多个ALV grid
- 小东吖 之 java的基础知识以及break 和 continue 关键字的使用
- 关于SSH的经典知识
- JAVA 与 MyCat(2) 单例模式
- STL(五)list 双向链表
- ToolBar的封装、动态改变状态栏颜色
- 20171130_tensorflow_tf.Variable
- CentOS7 下安装docker和docker-compose
- 面向对象(上)
- 获取python未知异常信息的方法
- 基于最小均方差(维纳)滤波的图像去模糊
- java.lang.NoSuchMethodError: redis.clients.jedis.JedisShardInfo.setTimeout(I)V