我平常再写单例模式时经常用这两种方法:

方法一:

public class SingletonDome {	//私有的构造方法是创建单例的基础	private SingletonDome(){		System.out.println("singletonDome create");	}	private static SingletonDome singleton = new SingletonDome();		public static SingletonDome getInstance(){		return singleton;	}}

方法二:

public class SingletonDome {	private SingletonDome(){		System.out.println("singletonDome create");	}	private static SingletonDome singleton = null;		public static synchronized SingletonDome getInstance(){		if(singleton==null){			singleton = new SingletonDome();		}		return singleton;	}}

第一种方法,在 JVM 加载单例类时,单例对象就会被建立,如果此时这个单例类在系统中还扮演其他角色,那么在任何使用这个单例类的地方都会初始化这个单例变量,而不管是否会被用到。

   缺点不能延迟加载

第二种方法,当用户第一次需要这个对象时才进创建,并时线程安全的,但是由于synchronized性能缺陷(之前我真没什么感觉..见测试用例)

public class LazySingleton implements Runnable{	 private LazySingleton(){	 System.out.println("LazySingleton is create");	 }	 private static LazySingleton instance = null;	 public static synchronized LazySingleton getInstance(){	 if(instance == null){	 instance = new LazySingleton();	 }	 return instance;	 }	 public static void createString(){	 System.out.println("create String");	 }	 	 @Override	 public void run() {	 // TODO Auto-generated method stub	 long beginTime = System.currentTimeMillis();	 for(int i=0;i<1000000;i++){	 LazySingleton.getInstance();	 }	 System.out.println(System.currentTimeMillis() - beginTime);	 }	 	 public static void main(String[] args){	 //LazySingleton.createString();	 for(int i=0;i<5;i++){	 new Thread(new LazySingleton()).start();	 }	 }	}打印:LazySingleton is createLazySingleton is createLazySingleton is createLazySingleton is createLazySingleton is createLazySingleton is create290593585598603

今天发现两种新的单例的写法:

静态内部类和枚举

静态内部类写法:

public class SingletonDome { private SingletonDome(){ System.out.println("singletonDome create"); } private static class SingletonHolder{ private static SingletonDome instance = new SingletonDome(); } public static SingletonDome getInstance(){ return SingletonHolder.instance; }}

测试:

public class LazySingleton implements Runnable {	private LazySingleton() {		System.out.println("LazySingleton is create");	}	private static class SingletonHolder {		private static LazySingleton instance = new LazySingleton();	}	public static LazySingleton getInstance() {		return SingletonHolder.instance;	}	public static void createString() {		System.out.println("create String");	}	@Override	public void run() {		// TODO Auto-generated method stub		long beginTime = System.currentTimeMillis();		for (int i = 0; i < 1000000; i++) {			LazySingleton.getInstance();		}		System.out.println(System.currentTimeMillis() - beginTime);	}	public static void main(String[] args) {		// LazySingleton.createString();		for (int i = 0; i < 5; i++) {			new Thread(new LazySingleton()).start();		}	}}运行效果如下:LazySingleton is createLazySingleton is createLazySingleton is createLazySingleton is createLazySingleton is createLazySingleton is create13111

备注:

    当 SingletonDome 被加载时,其内部类并不会被初始化,故可以确保当 SingletonDome 类被载入 JVM 时,不会初始化单例类,

    而当 getInstance() 方法调用时,才会加载 SingletonHolder,从而初始化 instance。

    同时,由于实例的建立是时在类加载时完成,故天生对多线程友好,getInstance() 方法也无需使用同步关键字。

枚举方式:

public enum AnimalHelperSingleton {    INSTANCE;    private AnimalHelperSingleton(){    }    public Animal[] buildAnimalList(){        final Animal[] animals = new Animal[10];        animals[0] = new SimpleAnimal(Animal.AnimalClass.MAMMAL,                 "Dog", true, Color.GRAY);        animals[1] = new SimpleAnimal(Animal.AnimalClass.MAMMAL,                 "Cat", true, Color.YELLOW);        animals[2] = new SimpleAnimal(Animal.AnimalClass.AMPHIBIAN,                "Frog", true, Color.GREEN);        animals[3] = new SimpleAnimal(Animal.AnimalClass.BIRD,                "Crow", true, Color.BLACK);        animals[4] = new SimpleAnimal(Animal.AnimalClass.BIRD,                "Cardinal", true, Color.RED);        animals[5] = new SimpleAnimal(Animal.AnimalClass.ARTHROPOD,                "Mantis", false, Color.GREEN);        animals[6] = new SimpleAnimal(Animal.AnimalClass.ARTHROPOD,                "Spider", false, Color.ORANGE);        animals[7] = new SimpleAnimal(Animal.AnimalClass.MAMMAL,                 "Tiger", true, Color.ORANGE);        animals[8] = new SimpleAnimal(Animal.AnimalClass.MAMMAL,                 "Bear", true, Color.BLACK);        animals[9] = new SimpleAnimal(Animal.AnimalClass.BIRD,                 "Owl", true, Color.BLACK);        return animals;    }}调用方式:Animal[] animals = AnimalHelperSingleton.INSTANCE.buildAnimalList();

优点:

1、 自由序列化;

2、 保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量);

3、 线程安全;

话说写单例用枚举的很少哎,而且感觉不是那么好理解。。。

单例--静态内部类摘自:http://www.ibm.com/developerworks/cn/java/j-lo-Singleton/ 

单例--枚举方式摘自:http://blog.csdn.net/horace20/article/details/37562513 

大家可以去看一下原文哦。