单例模式是一种非常常用的设计模式。下面备份下几种常用的单例模板。
github:
【 https://github.com/cstriker1407/design_pattern 】
CONTENTS
1)懒汉加载:
懒汉加载有很多实现方式,但很多方式都会有多线程同步问题,下面的这种方式规避了多线程的同步问题,并且实现了懒加载。它的核心方式是在单例类中加入了一个内部静态类。
public class Singleton_lazy { private static class Singleton_lazy_Holder { static { System.out.println("Singleton_lazy_Holder loaded"); } private static Singleton_lazy instance = new Singleton_lazy(); } private Singleton_lazy() { System.out.println("Singleton_lazy instance alloced"); } public static Singleton_lazy getInstance() { return Singleton_lazy_Holder.instance; } public void sayHello() { System.out.println("Hello"); } public static void donth() {} static { System.out.println("Singleton_lazy loaded"); } }
2)饿汉加载:
饿汉加载是作者最喜欢使用的一种单例实现方式。
{ private Singleton_hungry(){} private static Singleton_hungry instance = new Singleton_hungry(); public static Singleton_hungry getInstance() { return instance; } public void sayHello() { System.out.println("Hello From" + this.getClass().getName()); } }
3)使用枚举来实现一个单例:
作者在搜集单例的资料时发现了这种实现方式,但是并没有具体的在项目中应用。
package design_patterns.singleton; public enum Singleton_enum { INSTANCE; public void sayHello() { System.out.println("hello from enum,i=" + i); } private int i = 0; }
4)双重检测式 懒汉加载:
这种方式作者在很多资料上都有看到,但是实际中很少使用,而且这种方式在Java早期版本中是有缺陷的,详细的可以参考IBM的大牛的文章【 http://www.ibm.com/developerworks/cn/java/j-dcl.html 】。
public class Singleton_doublecheck { private static volatile Singleton_doublecheck instance = null; private Singleton_doublecheck(){} public static Singleton_doublecheck getInstance() { if (null == instance) { synchronized (Singleton_doublecheck.class) { if (null == instance) { instance = new Singleton_doublecheck(); } return instance; } } return instance; } public void sayHello() { System.out.println("Hello from Singleton_doublecheck"); } }
5)登记式单例:
作者并没有接触过这种单例模式,就现不在此处进行备份了。
单例模式的两个注意点:
1)不同类加载器的问题。
private static Class getClass(String classname) throws ClassNotFoundException { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if(classLoader == null) classLoader = Singleton.class.getClassLoader(); return (classLoader.loadClass(classname)); } }
2)Serializable接口问题。
public class Singleton implements java.io.Serializable { public static Singleton INSTANCE = new Singleton(); protected Singleton() { } private Object readResolve() { return INSTANCE; } }
部分代码参考:
发表评论