保证了一个类只有一个实例,并提供访问它的一个全局访问点。
属于创建者模式。
特点:保证了从项目启动到系统终止,全程只会产生一个实例。
应用场景:Listener本身、日历、IOC容器、配置信息等等
常见的设计模式:
1、饿汉式:Hungry.java
public class Hungry {
//私有化构造方法。
private Hungry(){};
//先静态后动态,先属性后方法。先上后下
private static final Hungry hungry = new Hungry();
public static Hungry getInstance(){
return hungry;
}
}
优点:线程安全。
缺点:浪费了内存
2、懒汉式1:
优点:开销小
缺点:非线程安全
public class Lazy {
private Lazy(){};
private static Lazy lazy = null;
public static Lazy getInstance(){
if(lazy==null){
lazy = new Lazy();
}
return lazy;
}
}
懒汉式2(加锁):
优点:线程安全
缺点:性能差
public class Lazy {
private Lazy(){};
private static Lazy lazy = null;
public static synchronized Lazy getInstance(){
if(lazy==null){
lazy = new Lazy();
}
return lazy;
}
}
懒汉式3(双重校验锁):
线程安全,且保持高性能。
public class Lazy {
private Lazy(){};
private volatile static Lazy lazy = null;
public static Lazy getInstance(){
if(lazy==null){
synchronized (Lazy.class){
if (lazy==null){
lazy = new Lazy();
}
}
}
return lazy;
}
}
懒汉4(静态内部类):
优点:性能好
缺点:利用反射机制,单例会被侵犯。
public class Lazy {
private Lazy(){};
private static class LazyHolder{
private static final Lazy lazy = new Lazy();
}
public static final Lazy getInstance(){
return LazyHolder.lazy;
}
}
懒汉5(改进内部静态模式):
兼顾饿汉式的内存浪费,也兼顾synchronized性能问题
public class Lazy {
private boolean initialized = false;
private Lazy(){
synchronized(Lazy.class){
if(initialized==false){
initialized = !initialized;
}else{
throw new RuntimeException("单例已被侵犯");
}
}
};
//默认不加载
private static class LazyHolder{
private static final Lazy lazy = new Lazy();
}
public static final Lazy getInstance(){
//在返回结果以前,一定会先加载内部类
return LazyHolder.lazy;
}
}
注册登记式:
spring的IOC容器就是典型的注册登记式。
public class Register {
private Register(){}
private static Map<String,Object> registerMap = new ConcurrentHashMap<>();
public Register getInstance(String name){
if(name==null){
name = Register.class.getName();
}
if(registerMap.get(name)==null){
registerMap.put(name,new Register());
}
return (Register)registerMap.get(name);
}
}
注册登记式之枚举式:
常量中使用
public enum Enum {
RED(){
private int r = 255;
private int g = 0;
private int b = 0;
},BLACK{
private int r = 0;
private int g = 0;
private int b = 0;
},WHITH(){
private int r = 0;
private int g = 0;
private int b = 0;
};
}