实现单例模式的思路是:
1,一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);
2,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;
3,同时我们还将该 类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。
1.饿汉式。指全局的单例实例在类装载时构建,当类第一次加载到内存中的时候就初始化了,所以创建的实例固然是thread-safe。
package com.open.design.singleton;
/**
* 饿汉式
* @author Administrator
*
*/
public class Singleton1 {
private final static Singleton1 instance=new Singleton1();
private Singleton1(){}
public static Singleton1 getInstance()
{
return instance;
}
}
package com.open.design.singleton;
/**
* 属于饿汉式,静态初始化。
* @author Administrator
*
*/
public class Singleton5 {
private static final Singleton5 instance;
static {
try {
instance = new Singleton5();
} catch (Exception e) {
throw new RuntimeException("Darn, an error occurred!", e);
}
}
private Singleton5() {}
public static Singleton5 getInstance() {
return instance;
}
}
2.懒汉式。
package com.open.design.singleton;
/**
* 懒汉式方式1
* @author Administrator
*
*/
public class Singleton2 {
private static Singleton2 instance = null;
private Singleton2() {}
public static Singleton2 getInstance()
{
if (instance == null)
{
instance = new Singleton2 ();
}
return instance;
}
}
package com.open.design.singleton;
/**
* 懒汉式方式2
* @author Administrator
*
*/
public class Singleton3 {
private static Singleton3 instance = null;
private Singleton3() {}
public static synchronized Singleton3 getInstance()
{
if (instance == null)
{
instance = new Singleton3 ();
}
return instance;
}
}
package com.open.design.singleton;
/**
* 懒汉式方式3
* @author Administrator
*
*/
public class Singleton4 {
private static volatile Singleton4 INSTANCE = null;
// Private constructor suppresses
// default public constructor
private Singleton4() {}
//thread safe and performance promote
public static Singleton4 getInstance()
{
if(INSTANCE == null)
{
synchronized(Singleton4.class)
{
//when more than two threads run into the first null check same time, to avoid instanced more than one time, it needs to be checked again.
if(INSTANCE == null)
{
INSTANCE = new Singleton4();
}
}
}
return INSTANCE;
}
}
(懒汉式方法3只能用在JDK5及以后版本(注意 INSTANCE 被声明为volatile),之前的版本使用“双重检查锁”会发生非预期行为[1])
3.虚拟机同步保证。完全使用了Java虚拟机的机制进行同步保证,没有一个同步的关键字。这种方式是Singleton类被装载了,instance不一定被初始化。因为SingletonHolder类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载SingletonHolder类,从而实例化instance。
package com.open.design.singleton;
/**
* 完全使用了Java虚拟机的机制进行同步保证,没有一个同步的关键字。
* @author Administrator
*
*/
public class Singleton6 {
// Private constructor prevents instantiation from other classes
private Singleton6() { }
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
public static final Singleton6 INSTANCE = new Singleton6();
}
public static Singleton6 getInstance() {
return SingletonHolder.INSTANCE;
}
}
4.枚举写法。因为创建枚举默认就是线程安全的,这个是针对jdk 1.5以及1.5版本以上的
package com.open.design.singleton;
/**
* 枚举写法
* @author Administrator
*
*/
public enum Singleton7 {
INSTANCE;
}
1.反射问题,除了枚举单例外,其它的单例方式均可以通过反射获取新的单例对象。
pac