设计模式--单例模式--第一天学习-创新互联

单例模式

网站建设哪家好,找创新互联公司!专注于网页设计、网站建设、微信开发、微信平台小程序开发、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了长寿免费建站欢迎大家使用!

单例模式的优点:

由于单例模式只生成一个实例,减少了系统性能开销,当一个对象产生需要比较多资源时,如读取配置,产生其他依赖对象时,则可以通过启动时直接产生一个单例对象,然后永久的驻留在内存的方式解决

单例模式的实现:

有五中方式

1.       饿汉式

2.       懒汉式

3.       双重检测锁实现

4.       静态内部类实现

5.       枚举类型实现

下边对五中类型做详细笔记

饿汉式单例模式

饿汉式特点:线程安全,调用效率高,但是不能延时加载

缺点:如果只是加载类,而不调用类中的方法,则会造成资源浪费

饿汉式实现:

1.       在定义类中定义一个静态变量,然后创建类对象赋值给静态变量,

2.       构造器要私有化

3.       定义静态方法返回静态变量

代码:

public class SingletonDemo1 {
//类初始化时,立即加载这个对象(没有延时加载的优势)。加载类时,天然的是线程安全的!
private static SingletonDemo1 instance = new SingletonDemo1(); 
private SingletonDemo1(){
}
//方法没有同步,调用效率高!
public static SingletonDemo1  getInstance(){
           return instance;
}
}

懒汉式单例模式

懒汉式特点:线程安全,调用效率不高,但是可以延时加载

缺点:资源利用率高了,但是每次调用getInstance()方法都要同步,并发效率低

懒汉式实现:

1.       在定义的类中定义一个私有的静态变量,不用赋值

2.       构造方法私有化

3.       对getInstance()方法加锁synchronized,方法中只创建一次对象,对静态变量赋一次值

代码:

public class SingletonDemo2 {
//类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)。
private static SingletonDemo2 instance; 
private SingletonDemo2(){ //私有化构造器
}
//方法同步,调用效率低!
public static  synchronized SingletonDemo2  getInstance(){
           if(instance==null){
                    instance = new SingletonDemo2();
           }
           return instance;
}
}

双重检测锁实现单例

双重检测锁特点:实现了懒加载和调用效率高的特点

缺点:由于编译器优化原因和jvm底层内部模型原因,偶尔会出现问题,不建议使用

双重检测锁实现:

public class SingletonDemo3 { 
 
  private static SingletonDemo3 instance = null; 
 
  public static SingletonDemo3 getInstance() { 
    if (instance == null) { 
      SingletonDemo3 sc; 
      synchronized (SingletonDemo3.class) { 
        sc = instance; 
        if (sc == null) { 
          synchronized (SingletonDemo3.class) { 
            if(sc == null) { 
              sc = new SingletonDemo3(); 
            } 
          } 
          instance = sc; 
        } 
      } 
    } 
    return instance; 
  } 
 
  private SingletonDemo3() { 
 
  } 
}

静态内部类实现单例

静态内部类特点:线程安全,调用效率高,懒加载

静态内部类单例实现:

1.       定义的类中定义一个静态内部类,静态内部类中定义一个静态常量,创建对象赋值给静态常量

2.       构造方法私有化

3.       定义getInstance()方法返回静态内部类中定义的静态常量

代码:

public class Singleto
nDemo4 {
private static class SingletonClassInstance {
           private static final SingletonDemo4 instance = new SingletonDemo4();
}
private SingletonDemo4(){
}
//方法没有同步,调用效率高!
public static SingletonDemo4  getInstance(){
           return SingletonClassInstance.instance;
}
}

枚举实现单例

枚举实现特点:线程安全,没有懒加载,调用效率高,实现简单,枚举本身就是单例模式,由JVM从根本上提供保障,避免通过反射和反序列化的漏洞

缺点:无延迟加载

枚举实现单例:

  1. 定义枚举类

  2. 在枚举类中定义一个元素

  3. 定义返回枚举中定义的元素

代码:

public enum SingletonDemo5 {
  
   //这个枚举元素,本身就是单例对象!
   INSTANCE;
  
   //添加自己需要的操作!
   public void singletonOperation(){
            System.out.println("枚举实现单例模式");
   }
}

单例模式总结

主要:

饿汉式(线程安全,调用效率高,不能延时加载)

懒汉式(线程安全,调用效率不高,可以延时加载)

其他

双重检测锁式(由于jvm底层内部模型原型,偶尔会出现问题,不建议使用)

静态内部类(线程安全,调用效率高,可以延时加载)

枚举式(线程安全,调用效率高,不能延时加载,并且可以天然的防止反射和反序列化漏洞)

如何选用?

单例对象 占用资源少,不需要延时加载

枚举好于饿汉式

单例对象 占用资源大,需要延时加载

静态内部类好于懒汉式


本文题目:设计模式--单例模式--第一天学习-创新互联
链接URL:http://ybzwz.com/article/diophp.html