– 由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置,产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式解决
– 单例模式可以在系统设置全局的访问点,优化共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。
– 主要:
饿汉式(线程安全,调用效率高,不能延时加载)
懒汉式(线程安全,调用效率不高,可以延时加载)
– 其他:
双重检测锁式(由于JVM底层内部模型原因,偶尔会出现问题,不建议使用)
静态内部类式(线程安全,调用效率高,可以延时加载)
枚举单例(线程安全,调用效率高,不能延时加载)
饿汉式
public class SingletonDemo1 {
// 1、私有构造器
// 2、提供静态属性
private static SingletonDemo1 instance = new SingletonDemo1();
// 私有化构造器
private SingletonDemo1() {
}
//方法没有同步,效率高
public static SingletonDemo1 getInstance() {
return instance;
}
}
懒汉式
public class SingletonDemo2 {
// 类初始化不创建对象,真正用时创建
private static SingletonDemo2 instance;
// 私有化构造器
private SingletonDemo2() {
}
// 方法同步,调用效率低
public static synchronized SingletonDemo2 getInstance() {
if(instance==null){
instance = new SingletonDemo2();
}
return instance;
}
}
双重检测锁
public class SingletonDemo1 {
// 由于编译器优化原因和JVM底层内部模型原因,偶尔出现问题,不建议使用
private static SingletonDemo1 instance = null;
public static SingletonDemo1 getInstance() {
if (instance == null) {
SingletonDemo1 s;
synchronized (SingletonDemo1.class) {
s = instance;
if (s == null) {
synchronized (SingletonDemo1.class) {
if (s == null) {
s = new SingletonDemo1();
}
}
instance = s;
}
}
}
return instance;
}
private SingletonDemo1() {
}
}
静态内部类
public class SingletonDemo1 {
// 外部类没有static属性,不会像饿汉式立即加载对象
// 只有调用了getInstance,才会加载静态内部类
// 兼备了并发高效调用和延时加载的优势
private static class SingletonInstance {
private static final SingletonDemo1 instance = new SingletonDemo1();
}
public static SingletonDemo1 getInstance() {
return SingletonInstance.instance;
}
private SingletonDemo1() {
}
}
枚举
public enum SingletonDemo1 {
/*
优点:
1、实现简单
2、避免通过反射和反序列化的漏洞
缺点:
无延时加载
*/
// 这个枚举元素本身就是单例的对象
INSTANCE;
// 添加自己需要的操作
public void aa() {
}
}