单例模式(Singleton)

一、核心特点

单例模式,是一种常用的软件设计模式。在它的核心结构中,只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,一个类只有一个实例。即 一个类只有一个对象实例。

二、应用场景

1.为了避免重复创建对象,浪费内存资源。
2.当多个线程同时访问同一资源时,保证数据安全。

三、设计思想

在JAVA中,对象是通过关键字new创建出来的,创建出来的对象被存放在堆内存里,它是始终存在的。
而方法的执行是在栈内存里,执行完就释放了消失了,所以方法是临时存在的。

·单例模式的特点:

1.私有的构造函数:

可以确保外部类无法通过构造方法,随便new出新的实例对象。

2.私有的静态的全局变量:

将唯一的一个实例对象,作为属性。
1>. 静态的,可以保证此实例对象是唯一存在的,
且外部类不需要通过创建此Singleton类,就可以直接获得这个实例对象。
2>. 私有的,可保证其他外部类,不能随便使用这个唯一的实例对象,保证数据安全。

3.公有的静态的方法:

向外部类提供 可以获得这个唯一实例对象的方法。
之所以是静态的,也是为了让外部类不需要创建对象,就可以直接使用这个方法。

四、实现过程

1.饿汉式创建:

Singleton类的创建:
在这里插入图片描述
主方法测试:(获得的是同一个对象)
在这里插入图片描述

2.懒汉式创建:

1>.首先,在属性那,先不创建那个唯一的实例。
由原来的 开局直接new对象在这里插入图片描述
改为只声明属性,不new对象
在这里插入图片描述
** 2>.唯一实例对象的创建以及返回,全靠那个静态的公有方法。**
为了返回不为空的实例对象,需要由原来的,只返回实例对象的操作
在这里插入图片描述
增加一个创建对象的过程。
在这里插入图片描述
为了防止,每次调用这个方法都需要new一次对象,所以,应该为它加一下判断条件。
在这里插入图片描述

3.多线程下的单例:

·给方法加锁 synchronized,保证在多线程访问的情况下,也只产生唯一的实例对象。
·添加锁 synchronized,保证了当前这个方法在整个执行过程中,只允许一个线程访问它。但同时也是它造成其他线程工作效率变慢的原因。

在这里插入图片描述

4.双重锁定

为"临界资源"添加锁 synchronized,
既解决了 多线程的安全问题,又提高了工作效率。

在这里插入图片描述

五、代码实现

1.饿汉式创建

 /**     1.饿汉式创建     */
    private Singleton(){} //构造函数
    private static Singleton instance = new Singleton(); //属性
    public static Singleton getInstance(){  //方法
        return instance;
    }

2.懒汉式创建

 /**     2.懒汉式创建     */
    private Singleton(){} //构造函数
    private static Singleton instance ; //属性
    public static Singleton getInstance(){ //方法
        if (instance == null){
            instance = new Singleton();
        }
        return instance;
    }

3.多线程下的单例

 /**
     * 3.多线程下的单例:
     * 给方法加锁 synchronized,保证在多线程访问的情况下,也只产生唯一的实例对象。
     * 添加锁 synchronized,保证了当前这个方法在整个执行过程中,只允许一个线程访问它。
     * 但同时也是它造成其他线程工作效率变慢的原因。
     */
    private Singleton(){} //构造函数
    private static Singleton instance ; //属性
    public synchronized static Singleton getInstance(){ //方法
        if (instance == null){
            instance = new Singleton();
        }
        return instance;
    }

4.双重锁定

/**
     * 4.双重锁定:
     * 既 解决了 多线程的安全问题,
     * 又提高了工作效率。
     */
    private Singleton(){} //构造函数
    private static Singleton instance ; //属性
    public static Singleton getInstance(){
        if (instance == null){
            /**     锁定的资源 为当前Singleton类     */
            synchronized(Singleton.class){
                if (instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

六、程序源码

1. Singleton类 的源码:

/**
 * 单例模式 singleton :
 * 实现此类只能创建一个唯一的实例对象。
 */

public class Singleton {


    /**
     * 1.私有的构造方法,
     * 可以确保外部类无法通过构造方法随便new出新的实例对象
     */
    private Singleton(){}


    /**
     * 2.将唯一的一个 实例对象instance,作为属性。
     *
     * 静态的static,可以保证此实例对象是唯一存在的,
     * 且外部类不需要通过创建此Singleton类,就可以直接获得instance对象.
     *
     * 私有的private,可保证其他外部类,不能随便使用这个唯一的实例对象,保证数据的安全。
     *
     * 添加 volatile :防止在给属性赋值的时候,JVM指定重排序。
     */
    private volatile static Singleton instance ;



    /**
     * 3.向外部类 提供 可以获得这个唯一实例对象的方法。
     *
     * 之所以是 静态的static,也是为了让外部类不需要创建对象,就可以直接使用这个方法.
     *
     * 为临界资源添加锁 synchronized,
     * 既 解决了 多线程的安全问题,又提高了工作效率。
     */
    public static Singleton getInstance(){
        if (instance == null){
            /**     锁定的资源 为当前Singleton类     */
            synchronized(Singleton.class){
                if (instance == null){
                    System.out.println("创建了一个对象!");
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }


    /**     1.饿汉式创建     */
//    private Singleton(){} //构造函数
//    private static Singleton instance = new Singleton(); //属性
//    public static Singleton getInstance(){  //方法
//        return instance;
//    }


    /**     2.懒汉式创建     */
//    private Singleton(){} //构造函数
//    private static Singleton instance ; //属性
//    public static Singleton getInstance(){ //方法
//        if (instance == null){
//            instance = new Singleton();
//        }
//        return instance;
//    }


    /**
     * 3.多线程下的单例:
     * 给方法加锁 synchronized,保证在多线程访问的情况下,也只产生唯一的实例对象。
     * 添加锁 synchronized,保证了当前这个方法在整个执行过程中,只允许一个线程访问它。
     * 但同时也是它造成其他线程工作效率变慢的原因。
     */
//    private Singleton(){} //构造函数
//    private static Singleton instance ; //属性
//    public synchronized static Singleton getInstance(){ //方法
//        if (instance == null){
//            instance = new Singleton();
//        }
//        return instance;
//    }



    /**
     * 4.双重锁定:
     * 既 解决了 多线程的安全问题,
     * 又提高了工作效率。
     */
//    private Singleton(){} //构造函数
//    private static Singleton instance ; //属性
//    public static Singleton getInstance(){
//        if (instance == null){
//            /**     锁定的资源 为当前Singleton类     */
//            synchronized(Singleton.class){
//                if (instance == null){
//                    instance = new Singleton();
//                }
//            }
//        }
//        return instance;
//    }

}

2. 测试程序的 main方法:

public class Test_main {
    public static void main(String[] args) {

        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();

        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s1 == s2);
    }
}

运行结果:
在这里插入图片描述

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值