首页 > 其他 > 详细

Singleton Pattern(单例模式)

时间:2020-09-26 18:09:48      阅读:33      评论:0      收藏:0      [点我收藏+]

单例模式:保证系统中一个类只会产生一个实例,主要解决一个全局使用的类频繁地创建与销毁。

好处

  1. 时间好处 - 省略频繁创建某个常用类对象的时间
  2. 空间好处 - 减少内存使用频率,减轻GC压力

单例模式角色

角色 作用
单例类 提供单例的工厂,返回单例
使用者 获取并使用单例类对象

技术分享图片

注意

1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。

饿汉式

优点:没有加锁,执行效率更高!
缺点:类加载时就初始化,浪费内存!

基于classloader机制避免多线程的同步问题,instance在类装载时候进行实例化,无法达到lazy loading效果!

public class Singleton {  
    
    private Singleton (){}  // private确保单例不会在系统中的其他代码内被实例化
    private static Singleton instance = new Singleton();
    // static修饰的方法在类加载的时候调用对单例对象实例化(即只要加载该类,单例对象自动实例化浪费空间
    public static Singleton getInstance() {  
    return instance;  
    }  
}

懒汉式

优点:只需要在第一次调用getInstance()方法的时候才会创建单例对象
缺点:为了确保线程安全问题需要添加volatile和synchronized关键字来保证线程安全但每次访问都需要同步会影响性能消耗更多资源

public class LazySingleton
{
    private static volatile LazySingleton instance=null;    //保证 instance 在所有线程中同步
    private LazySingleton(){}    //private 避免类在外部被实例化
    public static synchronized LazySingleton getInstance()
    {
        //getInstance 方法前加同步
        if(instance==null)
        {
            instance=new LazySingleton();
        }
        return instance;
    }
}
/* 为了使用延迟加载引入同步关键字反而降低了系统性能*/

懒汉式重构

单例模式使用内部类来维护单例的实例,当Singleton被加载时候不会对内部类进行实例化。只有调用getInstance方法时,才会加载内部类从而初始化单例对象

使用内部类的方式实现单例既可以做到延迟加载也不必使用同步关键字是一种完善的实现

public class Singleton {
    private Singleton(){}

    // 内部类SingletonHolder实现单例对象初始化
    private static class SingletonHolder{
        private static Singleton singleton = new Singleton();
    }

    public static Singleton getInstance(){
        // 调用内部类直接获得单例对象
        return SingletonHolder.singleton;
    }
}

实例

  • DBConnector模拟单例类
public class DBConnector {
    private DBConnector(){} // 私有构造方法,禁止在其他类创建单例对象

    private static class DBConnectorHolder{
        private static final DBConnector dbConnector = new DBConnector();
    }

    public static DBConnector getInstance(){
        return DBConnectorHolder.dbConnector;
    }
}

  • 测试
public class TestDemo {
    public static void main(String[] args) {
        DBConnector dbConnector01 = DBConnector.getInstance();
        DBConnector dbConnector02 = DBConnector.getInstance();
        System.out.println("dbConnector01内存地址: " + dbConnector01.toString());
        System.out.println("dbConnector02内存地址: " + dbConnector02.toString());

        System.out.println("dbConnector01的hashcode: " + dbConnector01.hashCode());
        System.out.println("dbConnector02的hashcode: " + dbConnector02.hashCode());

        System.out.println(dbConnector01 == dbConnector02);
    }
}
// 输出
dbConnector01内存地址: ink.openmind.base01.DBConnector@1c53fd30
dbConnector02内存地址: ink.openmind.base01.DBConnector@1c53fd30
dbConnector01的hashcode: 475266352
dbConnector02的hashcode: 475266352
true

Singleton Pattern(单例模式)

原文:https://www.cnblogs.com/openmind-ink/p/13734849.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!