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基本功的。在平时开发时要注意单例模式的使用场景,选择最优的方法实现单例。最后,建议在学习的过程中要思考单例模式的原理和为什么这么做,同时也要加以实践。

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

原文地址:https://www.cnblogs.com/xjl-raynor/p/13100697.html