单例模式
1、三大要点
(1)只能有一个实例
(2)自己创建实例
(3)必须自行向整个系统中提供这个实例
因此单例类中的构造方法必须是私有方法
2、饿汉式单例类
/**
* 饿汉式单例
* @author Administrator
*
*/
public class Singeton {
/**
* 加载对象时创建Singeton类
*/
private static Singeton instance = new Singeton();
/**
* 构造方法为私有
*/
private Singeton(){}
/**
* 获得单例对象
* @return
*/
public static Singeton getInstance(){
return instance;
}
}
当加载这个类时私有变量instance被初始化,单例中唯一的实例也就被创建了。
3、懒汉式单例
(1)通过synchronized解决多线程同步问题
/**
* 懒汉式单例
* @author Administrator
*
*/
public class Singeton {
private static Singeton instance = null;
/**
* 构造方法为私有
*/
private Singeton(){}
/**
* 获得单例对象
* 需要的时候创建对象
* @return
*/
public synchronized static Singeton getInstance(){
if(instance == null){
instance = new Singeton();
}
return instance;
}
}
懒汉式单例在第一次调用静态方法getInstance时实例化对象。这里主要在getInstance方法上使用了同步化是为了解决多线程问题。
(2)通过volidate解决多线程同步问题,并提高性能。
方法中添加synchronized时普通方法执行时间的100倍,因此我们下面采用volidate解决同步问题并提高性能
/**
* 懒汉式单例
* @author Administrator
*
*/
public class Singeton {
private static volidate Singeton instance = null;
/**
* 构造方法为私有
*/
private Singeton(){}
/**
* 获得单例对象
* 需要的时候创建对象
* @return
*/
public static Singeton getInstance(){
if(instance == null){
synchronized(Sington.class){
if(instance == null){
instance = new Singeton();
}
}
}
return instance;
}
}
这样就可以解决不用每次调用getInstance方法都执行同步操作,从而提高代码执行效率。
4、登记式单例
/**
* 登记式单例
* @author qiang
*
*/
public class Singeton {
private static Map<String, Singeton> cache = new HashMap<String, Singeton>();
static{
Singeton s = new Singeton();
cache.put("com.uwaysoft.desginmode.singeton.Singeton", s);
}
public static Singeton getInstance(String name){
if(name == null){
name = "com.uwaysoft.desginmode.singeton.Singeton";
}
if(cache.get(name) == null){
try {
Object obj = Class.forName(name);
cache.put(name, (Singeton)obj);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return cache.get(name);
}
}
为了解决懒汉式单例和饿汉式单例不能被继承的问题,因此出现了登记式单例