吐血整理全网最全的单例模式

2020/2/22 17:02:51

本文主要是介绍吐血整理全网最全的单例模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前言

之前文章已经说过了设计模式的七大原则,即接口屏蔽原则,开闭原则,依赖倒转原则,迪米特原则,里氏替换原则,单一职责原则,合成复用原则,不明白的,可以移至XXXX(代写)。从今天开始我们就要学习一些常见的设计模式,方便我们以后看源码使用,当然,也可以指导我们平常的编码任务。

我们常见的设计模式主要有23种,分为3种类型,咱也不全说,只写重要的几个把。

创建型:单例模式,工厂模式,原型模式

结构型:适配器模式,装饰模式,代理模式

行为型:模板模式,观察者模式,状态模式,责任链模式

单例模式的概念和作用

概念

系统中只需要一个全局的实例,比如一些工具类,Converter,SqlSession等。

为什么要用单例模式?

  • 只有一个全局的实例,减少了内存开支,特别是某个对象需要频繁的创建和销毁的时候,而创建和销毁的过程由jvm执行,我们无法对其进行优化,所以单例模式的优势就显现出来啦。
  • 单例模式可以避免对资源的多重占用,避免出现多线程的复杂问题。

单例模式的写法重点

构造方法私有化

我们需要将构造方法私有化,而默认不写的话,是公有的构造方法,外部可以显式的调用来创建对象,我们的目的是让外部不能创建对象。

提供获取实例的公有方法

对外只提供一个公有的的方法,用来获取实例,而这个实例是否是唯一的,单例的,由方法决定,外部无需关心。

单例模式的常见写法(如下,重点)

饿汉式和懒汉式的区别

饿汉式

饿汉式,从名字上也很好理解,就是“比较饿”,迫不及待的想吃饭,实例在初始化的时候就已经建好了,不管你有没有用到,都先建好了再说。

懒汉式

饿汉式,从名字上也很好理解,就是“比较懒”,不想吃饭,等饿的时候再吃。在初始化的时候先不建好对象,如果之后用到了,再创建对象。

1.饿汉式(静态变量)--可以使用

A类

public class A {
    //私有的构造方法
    private A(){}
    //私有的静态变量
    private final static A a=new A();
    //对外的公有方法
    public static A getInstance(){
        return a;
    }
}复制代码

测试类

public class test {
    public static void main(String[] args){
        A a1=A.getInstance();
        System.out.println(a1.hashCode());

        A a2=A.getInstance();
        System.out.println(a2.hashCode());
    }
}复制代码

运行结果


说明

该方法采用的静态常量的方法来生成对应的实例,其只在类加载的时候就生成了,后续并不会再生成,所以其为单例的。

优点

在类加载的时候,就完成实例化,避免线程同步问题。

缺点

没有达到懒加载的效果,如果从始到终都没有用到这个实例,可能会导致内存的浪费。

2.饿汉式(静态代码块)--可以使用

A类

public class A { 
    //私有的构造方法
     private A(){}
    //私有的静态变量
     private final static A a; 
    //静态代码块 
    static{ a=new A(); } 
    //对外的公有方法
    public static A getInstance(){
     return a; 
    }
}复制代码

测试类

public class test {
    public static void main(String[] args){
        A a1=A.getInstance();
        System.out.println(a1.hashCode());

        A a2=A.getInstance();
        System.out.println(a2.hashCode());
    }
}复制代码

运行结果


说明

该静态代码块的饿汉式单例模式与静态变量的饿汉式模式大同小异,只是将初始化过程移到了静态代码块中。

优点缺点

与静态变量饿汉式的优缺点类似。

3.懒汉式

A类

public class A {
    //私有的构造方法
    private A(){}
    //私有的静态变量
    private  static A a;
    //对外的公有方法
    public static A getInstance(){
        if(a==null){
            a=new A();
        }
        return a;
    }
}复制代码

测试类和运行结果

同上。

优点

该方法的确做到了用到即加载,也就是当调用getInstance的时候,才判断是否有该对象,如果不为空,则直接放回,如果为空,则新建一个对象并返回,达到了懒加载的效果。

缺点

当多线程的时候,可能会产生多个实例。比如我有两个线程,同时调用getInstance方法,并都到了if语句,他们都新建了对象,那这里就不是单例的啦。

4.懒汉式(线程安全,同步方法)--可以使用

public class A {
    //私有的构造方法
    priva
                   

这篇关于吐血整理全网最全的单例模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程