1.设计需考虑的问题:
线程安全性内存消耗性能是否会被破坏
2.特点:
任何情况下都有一个实例提供一个全局访问点隐藏所有构造方法创建型模式
3.实现方式:
饿汉式懒汉式注册式ThreadLocal
饿汉式
法一:
public class HungrySingleton{
private static final HungrySingleton hs
= new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton
getInstance(){return hs
;}
}
法二:
public class HungrySingleton{
private static final HungrySingleton hs;
static{
hs
= new HungrySingleton();
}
private HungrySingleton(){}
public static HungrySingleton
getInstance(){return hs
;}
}
线程安全
内存开销大
懒汉式
法一:线程不安全
public class LazySingleton{
private static LazySingleton instance
= null
;
private LazySingleton(){}
public static LazySingleton
getInstance(){
if(null
== instance
){
instance
= new LazySingleton();
}
return instance
;
}
}
内存开销小
线程不安全
法二:同步方法解决线程不安全(
synchronized),性能低,
public class LazySingleton{
private static LazySingleton instance
= null
;
private LazySingleton(){}
public static synchronized LazySingleton
getInstance(){
if(null
== instance
){
instance
= new LazySingleton();
}
return instance
;
}
}
法三:
double-check解决线程不安全,由类阻塞变为方法阻塞,提高性能
public class LazySingleton{
private static LazySingleton instance
= null
;
private LazySingleton(){}
public static LazySingleton
getInstance(){
synchronized(LazySingleton
.class){
if(null
== instance
){
instance
= new LazySingleton();
}
}
return instance
;
}
}
优化:
***
public class LazySingleton{
private volatile static LazySingleton instance
= null
;
private LazySingleton(){}
public static LazySingleton
getInstance(){
if(null
== instance
){
synchronized(LazySingleton
.class){
if(null
== instance
){
instance
= new LazySingleton();
}
}
}
return instance
;
}
}
法四:内部类,优雅,利用语法优势
public class LazyInnerClassSingleton{
private LazyInnerClassSingleton(){}
public static final LazyInnerClassSingleton
getInstance(){
return LazyHolder
.INSTANCE
;
}
private static class LazyHolder{
private static final LazyInnerClassSingleton INSTANCE
= new LazyInnerClassSingleton();
}
}
以上方式的私有构造函数不安全,反射能破坏,改写如下:
private LazyInnerClassSingleton(){
if(LazyHolder
.INSTANCE
!= null
){
throw new RuntimeException();
}
}
注册式:官方推荐,最优雅
public enum EnumSingleton
{
INSTANCE
;
private Object data
;
public Object
getData(){return data
;}
public void setData(Object data
){this.data
=data
;}
public static EnumSingleton
getInstance(){return INSTANCE
;}
}
public ContainSingleton
{}