Code,  Study,  Tech

Java设计模式之单例模式

设计模式是Java进阶的必备知识。以前跟着开发项目时用过单例模式,但那时也只是依葫芦画瓢,对“单例”的概念和实现并无真正的了解与思考。今天找了些资料来补习,笔记记录下。

一.单例概念

在面向对象编程时,有时我们需要的对象只要有一个实例就够了,称之为单例。

单例设计模式属于创建型模式,原则如下:

1.单例类只能有一个实例。

2.单例类必须自己创建自己的唯一实例。

3.单例类必须给所有其他对象提供这一实例。

什么情况下需要使用单例呢?

在某些时候,若创造出多个实例,可能会导致过多资源占用或不一致等问题,这时候就要采用单例来设计了。比如我们常说的“一山容不下二虎”,此山有一🐱那其他都是Hello Kitty,山中唯一的🐱就是单例存在。再比如渣男渣女找对象不是单例的,若他的各对象是以单例模式找的他,就会因资源分配混乱和不一致的出现扯皮撕逼。所以生活中使用单例模式对待某些严肃的问题,才是好好做人啦…扯远了~

经典的单例实现方法有懒汉模式与饿汉模式两种。下面分别介绍其实现方法。

二.饿汉模式

所谓饿汉,可以理解成此时的类是个很饿的仔,真的很需要这个实例馒头(或面包?)立马来填饱肚子,所以这个仔一出现就要甩他一个面包,不然他就会被饿死。用专业术语来说就是:类在初始化的时候就要进行实例化。

特点:

  1. 由于类在初始化时就进行实例化,加载类时会相对较慢。
  2. 若实例用不上,就会产生垃圾对象,造成内存浪费。
  3. 线程安全。

使用场合:

若单例模式的实例在系统中经常会被用到,就选择饿汉式(一劳永逸)。

代码实现-类定义 : StarveSingleton.java

public class StarveSingleton {
    //1.将构造方法私有化,不允许外部直接创建对象
    private StarveSingleton(){
    }

    //2.创建类的唯一实例,使用private static修饰
    private static StarveSingleton instance=new StarveSingleton();

    //3.提供一个用于获取实例的方法,使用public static修饰
    public static StarveSingleton getInstance(){
        return instance;
    }
}

代码实现-主函数调用:Test.java

public class Test {
    public static void main(String[] args) {
        //饿汉模式 
        StarveSingleton s1 = StarveSingleton.getInstance();
        StarveSingleton s2 = StarveSingleton.getInstance();
        if (s1 == s2) {
            System.out.println("s1和s2是同一个实例");
        } else {
            System.out.println("s1和s2不是同一个实例");
        }
    }
}

执行输出:

s1和s2是同一个实例

三.懒汉模式

所谓懒汉,可以理解成此时的类是个很懒的仔,他真的很懒,懒得在一开始就考虑那么多那么全面。只有等到事情来了要用什么他才会去好好准备。用专业术语来说就是:类初始化时不考虑其实例化,当程序需要访问到单例实例的时候再去创建它。

特点:

  1. 由于类在初始化时就没有实例化,加载类时会相对较快。
  2. 第一次调用才初始化,避免了内存浪费。
  3. 线程不安全。

使用场合:

若单例模式的实例在系统中很少用到或者几乎不会用到,选择懒汉式(减少浪费,人人有责)。

代码实现-类定义:LazySingleton.java

public class LazySingleton {
    //1.将构造方式私有化,不允许外边直接创建对象
    private LazySingleton(){
    }

    //2.声明类的唯一实例,使用private static修饰
    private static LazySingleton instance;

    //3.提供一个用于获取实例的方法,使用public static修饰
    public static LazySingleton getInstance(){
        if(instance==null){
            instance=new LazySingleton();
        }
        return instance;
    }
}

代码实现-主函数调用:Test.java

public class Test {
    public static void main(String[] args) {
        //懒汉模式
        LazySingleton s3=LazySingleton.getInstance();
        LazySingleton s4=LazySingleton.getInstance();
        if(s3==s4){
            System.out.println("s3和s4是同一个实例");
        }else{
            System.out.println("S3和s4不是同一个实例");
        }

    }
}

执行输出:

s3和s4是同一个实例

更多资料参考:

模式的秘密—单例模式

设计模式(Design pattern)– 单例模式

发表评论

电子邮件地址不会被公开。 必填项已用*标注