zoukankan      html  css  js  c++  java
  • java设计模式:单例模式

    一、前言

    java的设计模式的应用非常常见,是一套被反复使用的、分类编目的代码设计经验总结。使用设计模式可以提高代码的复用性,有利于代码的维护和拓展。

    在设计模式中按照不同的处理方式可以分为三类:

    创建型:对象实例化的模式,创建型模式用于解耦对象的实例化过程。

    结构型:把类或对象结合在一起形成一个更大的结构。

    行为型:类和对象如何交互,及划分责任和算法。

    二、单例模式(Singletion)介绍

    首先单例模式属于创建型。

    单例模式较其他设计模式相对简单,其应用也相对较常见,在一些项目中的使用非常多。

    单例模式:保证一个类仅用一个实例,并且提供一个全局的访问点。也就是说我们让一个类在全局只有一个可以访问的实例,这个唯一的实例有它自身创建并保存。由此可以看出单例模式主要解决的问题是,一个全局使用的类频繁的创建和消费。通过单例模式来提高整体项目代码的性能。

    结构图:

    Singleton:定义GetInstrance()方法。

    GetInstrance():创建自己的唯一实例。

    三、单例模式的实现

    1、懒汉模式(线程不安全)

    public class lazy {
        private static lazy instance;
        public static lazy getInstance() {  
            if (instance == null) {  
                instance = new lazy();  
            }  
            return instance;  
            }  
    
    }

    单例模式不允许在外部直接创建实例,通过private来进行限制,懒汉模式实现延时加载(懒加载)。但是此种方法存在问题,当多个访问同时获取对象的实例时,会出现多个相同的实例并存,这样有违单例模式的原理。

    2、懒汉模式(线程安全)

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

    此方法在获取实例的方法上添加了线程锁,让其变为线程安全的。但是由于锁加在方法上,所以所有访问都会触发锁,会引起资源的浪费,这样的使用方法就是见仁见智了。

    3、饿汉模式(线程安全)

    public class hungry {
        private static hungry instance;
        public static hungry getInstance() {  
            return instance;  
        }  
    
    }

    此方法并不是延时加载(懒加载),也就是说不管你用不用的到这个类,都会在程序启动时创建实例,这样会造成一定资源占用。举个例子:你用电脑玩游戏,在进入游戏后,游戏把所有场景都加载出来(游戏过程只使用一个场景),导致内存占用过高,产生卡顿。

    4、双重锁模式(线程安全)

    public class doubleLock {
        private volatile static doubleLock singleton;
        public static doubleLock getSingleton() {  
            if (singleton == null) {  
                synchronized (doubleLock.class) {  
                    if (singleton == null) {  
                        singleton = new doubleLock();  
                    }  
                }  
            }  
            return singleton;  
        }  
    
    }

    此方法满足线程安全,同时也实现了延时加载(懒加载)。

    5、使用内部类(线程安全)

    public class Singleton {
        
        private static class SingletonIn{
            private static Singleton instance = new Singleton();
        }
        
        public static Singleton getInstance() {
            return SingletonIn.instance;
        }
    
    }

    此方法既保证了线程安全又实现了延时加载(懒加载),同时也解决了加锁的性能消耗。

    还有CAS和Effective两种实现模式,由于笔者接触较少,再此就不做过多介绍了。

    四、总结

    虽然单例模式比较常见和简单,但是在各种的实现上还是比较考验java基本功的。在平时开发时要注意单例模式的使用场景,选择最优的方法实现单例。最后,建议在学习的过程中要思考单例模式的原理和为什么这么做,同时也要加以实践。

    每日一笑:我和儿子有个共同的心愿,出国旅游。昨天儿子考试得了全班第一,我跟媳妇合计着带他出国见见世面,吃晚饭的时候,一家人开始了讨论这个。我:“儿子,你的心愿是什么?”,儿子:“吃汉堡包”,我:“往大了说”,儿子:“变形金刚”,我:“今天你爹说了算,想想咱俩共同的心愿”,儿子怯生生的瞅了媳妇一眼说:“换个妈?",我心里咯噔一下:“这虎犊子,坑自己也就算了,怎么还坑爹呢”。

  • 相关阅读:
    spring注解集合
    spring工作原理理解
    Linux下mysql命令 导入 导出sql文件
    List和Set排序的实现
    LeetCode--树
    LeetCode--链表
    LeetCode--字符串
    LeetCode--贪心算法
    LeetCode--数组
    数据库编程基本练习题
  • 原文地址:https://www.cnblogs.com/xjl-raynor/p/13100697.html
Copyright © 2011-2022 走看看