单例模式分为三种:饿汉式单例,懒汉式单例,登记式单例
单例模式的特点:
1.单例只有一个实例
2.单例的实例对象都是自己实例化出来的
3.单例类必须给其他的对象提供这个唯一的实例
饿汉式单例:
package pattern.singleton;
/**
* 饿汉式单例模式:在类被加载的时候,唯一实例已经被创建
*/
public class HungrySingleton {
public static final HungrySingleton singleton = new HungrySingleton();
private HungrySingleton(){} //私有构造方法,避免外部创建实例
public static HungrySingleton getInstance(){
return singleton;
}
}
package pattern.singleton;
/**
* 通用的饿汉式单例模式 ,解决多线程访问的问题
*/
public class SingletonPattern {
private static final SingletonPattern singletonPattern = new SingletonPattern();
private SingletonPattern(){}//私有构造方法,避免外部创建实例
public static synchronized SingletonPattern getInstance(){
return singletonPattern;
}
}
懒汉式单例:
package pattern.singleton;
/**
* 懒汉单例模式:只有在第一次请求实例的时候的时候创建,并且只在第一次创建后,以后不再创建该类的实例。
*/
public class LazySingleton {
private static LazySingleton singleton = null;
private LazySingleton(){} //私有构造方法,避免外部创建实例
public static LazySingleton getInstance(){
if(singleton == null){
singleton = new LazySingleton();
}
return singleton;
}
}
package pattern.singleton;
/**
* 通用的懒汉式单例模式 ,解决多线程访问的问题
*/
public class SingletonPattern {
private static SingletonPattern singletonPattern = null;
private SingletonPattern(){}//私有构造方法,避免外部创建实例
public static synchronized SingletonPattern getInstance(){
if(singletonPattern == null){
singletonPattern = new SingletonPattern();
}
return singletonPattern;
}
}
登记式单例:
package pattern.singleton;
import java.util.HashMap;
import java.util.Map;
/**
* 登记式单例实际上维护的是一组单例类的实例,将这些实例存放在一个Map(登记薄)中,对于已经登记过的实例,
* 则从工厂直接返回,对于没有登记的,则先登记,而后返回.
* 登记式单例类是为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的.当单例类需要被继承时适用.
*/
public class RegisterSingleton {
private static Map<String, RegisterSingleton> map = new HashMap<String, RegisterSingleton>();
static {
RegisterSingleton singleton = new RegisterSingleton();
map.put(singleton.getClass().getName(), singleton);
}
protected RegisterSingleton() {}// 受保护的构造函数
public static RegisterSingleton getInstance(String name) {
if (name == null) {
name = RegisterSingleton.class.getName();
System.out.println(name);
}
if (map.get(name) == null) {
try {
map.put(name, (RegisterSingleton) Class.forName(name)
.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
return map.get(name);
}
}
package pattern.singleton;
public class RegisterSingletonChild extends RegisterSingleton{
public static RegisterSingletonChild getInstance(){
return (RegisterSingletonChild)RegisterSingleton.getInstance("pattern.singleton.RegisterSingletonChild");
}
public static void main(String[] args) {
RegisterSingletonChild.getInstance();
RegisterSingleton.getInstance("pattern.singleton.RegisterSingletonChild");
}
}