单例模式:属于创建型模式。项目中只存在某个类的一个对象,而且只可能存在一个对象。那么我们说这个类是单例模式,也叫单态模式。
单例模式分为两种 :懒汉式 和 饿汉式。
饿汉式
package com.pattern.build.singleton;
/**
* 饿汉式
* @author chuer
* @date 2014-7-17 下午5:16:21
* @version V1.0
*/
public class HungrySingleton {
//私有化构造方法
private HungrySingleton(){ }
//new一个实例
private static HungrySingleton singleton = new HungrySingleton();
//获得实例
public static HungrySingleton getInstance(){
return singleton;
}
}
分析:
1:怎么保证一个类只存在一个对象呢?
那就是使这个类的构造方法私有化。这样就禁止了这个类在其他类中new,也就是只能在本类中new。
因为叫单例,所以我们通常只在本类中new一个对象,如果需要你也可以在本类中new多个对象(我叫它非主流单例)。
2:外部怎么得到这个对象呢?
只有唯一的一种方法,就是提供类方法(静态方法)来获取此类的对象。
那么我们必须使用类变量来指向这个对象(因类方法是不能访问成员变量的)。
3:单例模式有什么用呢?
最常见应用比如连接池的实现。我们一个项目中一般只需要一个连接池,而且只需要一个连接池的对象。
再比如你要把数据库的某些数据在内存中缓存一份儿,那么这个缓存类只能有一个对象,毕竟我们只想缓存一份儿。
数据库连接池的实现,可以参考http://blog.csdn.net/maosijunzi/article/details/37822111
懒汉式
package com.pattern.build.singleton;
public class LazySingleton {
// 私有化构造方法
private LazySingleton() { }
//类变量
private static LazySingleton singleton = null;
// 获得实例
public static synchronized LazySingleton getInstance() {
if (singleton == null) {
singleton = new LazySingleton();//第一次访问时new实例
}
return singleton;
}
}
懒汉式和饿汉式的区别:
创建实例的时机不同,懒汉在第一次访问的时候创建实例,而饿汉在类加载的时候初始化(类加载时会初始化静态数据)。
懒汉式缺点:大家也注意到了懒汉式在静态方法上加上了同步,也就是不加同步的话会存在线程安全问题(像这种有共享
资源的先判断后执行的代码一般都存在线程安全问题),
如果多个线程同时判断都为null,那么就会实例化多次了。所以必须加同步,除非你能保证你的代码不会在多线程下运行。
加了同步又会出现性能问题,多个线程
访问的时候必须排队。唉,这就是延迟初始化,带来的麻烦。
饿汉式缺点:举个极端的例子,如果一个项目中,有100个单例模式,而且每个模式的初始化都很耗时,假如需要1分钟。
那么所有的单例都是饿汉式的话,项目启动 需要100分钟,我的天啊!!!!我去死..如果用懒汉式就不同了,
分分钟项目起来了,只是在使用每个单例的时候消耗1分钟就行,是不是很爽。
总结:单例模式是使用很广泛的一种设计模式。两种实现方式各有优缺点,他们的优点同时又是他们的缺点。世界本来就是
矛盾的啊。可以根据自己的需求选择使用哪一种方式来实现。
完美单例
public class Singleton {
private Singleton() {}
public Singleton getInstance() {
return SingletonHolder.singleton;
}
private static class SingletonHolder{
public static Singleton singleton = new Singleton();
}
}