实现方法一
package com.hs.pattern.singleton;
/**
* 优点:实现简单
* 缺点:线程不安全
* 例如:当两个线程都运行到if( singleton == null ),而singleton确实为空,则两个线程都会创建一个实例
* @author Administrator
*
*/
public class Singleton1 {
private static Singleton1 singleton = null;
private Singleton1(){}
public Singleton1 getInstance(){
if( singleton == null ){
singleton = new Singleton1();
}
return singleton;
}
}
实现方法二
package com.hs.pattern.singleton;
/**
* 懒汉模式
* 优点:线程安全、lazy-loading
* 缺点:每次调用getInstance方法都要获取锁,效率低
* @author Administrator
*
*/
public class Singleton2 {
private static Singleton2 singleton = null;
private Singleton2(){}
public synchronized Singleton2 getInstance(){
if( singleton == null ){
singleton = new Singleton2();
}
return singleton;
}
}
实现方法三
package com.hs.pattern.singleton;
/**
* 双重检查锁
* 优点:只有singleton为空、需要创建实例时才需要获取锁,效率高且线程安全
* 缺点:如果需要实现序列化,则可以通过序列化、反序列化获取多个实例
* @author Administrator
*
*/
public class Singleton3 {
private static Singleton3 singleton = null;
private Singleton3(){}
public Singleton3 getInstance(){
if( singleton == null ){
synchronized (Singleton3.class) {
if( singleton == null ){
singleton = new Singleton3();
}
}
}
return singleton;
}
}
实现方案四
package com.hs.pattern.singleton;
/**
* 饿汉模式
* 优点:实现简单、线程安全
* 缺点:没有实现lazy-loading
* @author Administrator
*
*/
public class Singleton4 {
private static Singleton4 singleton = new Singleton4();
private Singleton4(){}
public Singleton4 getInstance(){
return singleton;
}
}
实现方案五
package com.hs.pattern.singleton;
/**
* 静态内部类
* 优点:由于SingletonHolder是静态的,所以只有首次调用时才会初始化,因为SingletonHolder是私有内部类,
* 所以只有调用Singleton5.getInstance()方法是才会初始化,从而实现lazy-loading
* 缺点:如果需要实现序列化,则可以通过序列化、反序列化获取多个实例
* @author Administrator
*
*/
public class Singleton5 {
private Singleton5(){}
private static class SingletonHolder{
public final static Singleton5 singleton = new Singleton5();
}
public static Singleton5 getInstance(){
return SingletonHolder.singleton;
}
}
实现方案六
package com.hs.pattern.singleton;
/**
* 枚举类实现单例
* 优点:对于序列化、反序列化,因为每个枚举类型和每个枚举变量在jvm中都是唯一的,
* 即Java在序列化和反序列化枚举时做了特殊的规定,枚举的writeObject、
* readObject、readObjectNoData、writeReplace和readResolve
* 等方法是被编译器禁用的,因此也不存在实现序列化接口后调用readObject会破坏单例的问题。
* 缺点:实现比较复杂
* @author Administrator
*
*/
public class Singleton6 {
private Singleton6(){}
public static Singleton6 getInstance(){
return SingletonEnum.INSTANCE.getSingleton();
}
private static enum SingletonEnum{
INSTANCE;
private Singleton6 singleton ;
private SingletonEnum(){
singleton = new Singleton6();
}
public Singleton6 getSingleton(){
return singleton;
}
}
}