1.饿汉模式 使用类公有的静态成员来保存该唯一对象
public class EagerSingleton {
// jvm保证在任何线程访问uniqueInstance静态变量之前一定先创建了此实例
public static EagerSingleton uniqueInstance = new EagerSingleton();
// 私有的默认构造子,保证外界无法直接实例化
private EagerSingleton() {
}
}
2.饿汉模式 使用公有的静态成员工厂方法
public class EagerSingleton {
// jvm保证在任何线程访问uniqueInstance静态变量之前一定先创建了此实例
private static EagerSingleton uniqueInstance = new EagerSingleton();
// 私有的默认构造子,保证外界无法直接实例化
private EagerSingleton() {
}
// 提供全局访问点获取唯一的实例
public static EagerSingleton getInstance() {
return uniqueInstance;
}
}
3.懒汉式
同步一个方法可能造成程序执行效率下降100倍,完全没有必要每次调用getInstance都加锁,事实上我们只想保证一次初始化成功,其余的快速返回而已,如果在getInstance频繁使用的地方就要考虑重新优化了.
1.静态内部类单例模式
public class Singleton {
private Singleton(){
}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static class SingletonHolder {
private static final Singleton sInstance = new Singleton();
}
}
public class LazySingleton {
private static LazySingleton uniqueInstance;
private LazySingleton() {
}
public static synchronized LazySingleton getInstance() {
if (uniqueInstance == null)
uniqueInstance = new LazySingleton();
return uniqueInstance;
}
}
4."双检锁"(Double-Checked Lock)尽量将"加锁"推迟,只在需要时"加锁"(仅适用于Java 5.0 以上版本,volatile保证原子操作)
public class DoubleCheckedLockingSingleton {
// java中使用双重检查锁定机制,由于Java编译器和JIT的优化的原因系统无法保证我们期望的执行次序。
// 在java5.0修改了内存模型,使用volatile声明的变量可以强制屏蔽编译器和JIT的优化工作
private volatile static DoubleCheckedLockingSingleton uniqueInstance;
private DoubleCheckedLockingSingleton() {
}
public static DoubleCheckedLockingSingleton getInstance() {
if (uniqueInstance == null) {
synchronized (DoubleCheckedLockingSingleton.class) {
if (uniqueInstance == null) {
uniqueInstance = new DoubleCheckedLockingSingleton();
}
}
}
return uniqueInstance;
}
}
5 使用枚举类的方式来实现单例(强烈推荐的实现方式)
public enum SingletonClass {
INSTANCE;
private String name;
public void test() {
System.out.println("The Test!");
}
public void setName(String name){
this.name= name;
}
public String getName(){
return name;
}
}
public class TestMain {
public static void main(String[] args) {
SingletonClass one = SingletonClass.INSTANCE;
SingletonClass two = SingletonClass.INSTANCE;
one.test();
one.setName("I am a SingletonClass Instance");
System.out.println(one.getName());
if (one == two) {
System.out.println("There are same");
}
}
}
- 使用容器实现单例模式
public class SingletonManager {
private static Map<String, Object> objMap = new HashMap<String,Object>();
private Singleton() {
}
public static void registerService(String key, Objectinstance) {
if (!objMap.containsKey(key) ) {
objMap.put(key, instance) ;
}
}
public static ObjectgetService(String key) {
return objMap.get(key) ;
}
}
总结,实现单例模式的唯一推荐方法,使用枚举类来实现。使用枚举类实现单例模式,在对枚举类进行序列化时,还不需要添加readRsolve方法就可以避免单例模式被破坏。
网友评论