文档章节

单例模式(Singletion)

SunnyTime
 SunnyTime
发布于 2016/09/22 15:44
字数 977
阅读 57
收藏 1

单例模式(Singletion),我估计大家用到比较多.我使用的第一个设计模式就是单利模式.

单例模式是为了确保一个类有且仅有一个实例,并为它提供一个全局访问点.简单说就是你不能new一个实例出来.


举一个例子,比如在我的开发中有这样一种情况,我们有同事写了一组地图工具MapUtils.java,我们在不同的使用地方来调用这个工具类,为了避免有多个工具类实例存在就使用单利模式.

一、懒汉单利模式模式

public class MapUtils {

    private MKSearch           mkSearch;
    private LocationClient     locationClient;
    private OnLocationListener listener;

    private static MapUtils    instance;

    private MapUtils() {
    }

    public static MapUtils getInstance(Context context) {
        if (null == instance) {
            instance = new MapUtils(context.getApplicationContext());
        }
        return instance;
    }
}

构造函数为private,这样就不能使用new来创建实例.唯一实例只能通过getInstance()方法访问。(事实上,通过Java反射机制是能够实例化构造方法为private的类的,那基本上会使所有的Java单例实现失效。此问题在此处不做讨论.)

上面的单例模式为懒汉单例模式,懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个MapUtils实例,要实现线程安全,有以下三种方式,都是对getInstance这个方法改造,保证了懒汉式单例的线程安全,如果你第一次接触单例模式,对线程安全不是很了解,可以先跳过下面这三小条,去看饿汉式单例,等看完后面再回头考虑线程安全的问题.

1、在getInstance方法上加同步

public static synchronized MapUtils getInstance(Context context) {  
	if (null == instance) {    
	    instance = new MapUtils(context.getApplicationContext());
	}    
	return instance;  
}

2、双重检查锁定

public static MapUtils getInstance(Context context) {
    if (null == instance) {
        synchronized (MapUtils.class) {
            if (null == instance) {
                instance = new MapUtils(context.getApplicationContext());
            }
        }
    }
    return instance;
}

3、静态内部类

public class MapUtils {
    private static class LazyHolder {
        private static Context context;
        private static final MapUtils INSTANCE = new MapUtils(context.getApplicationContext());
    }
    private MapUtils(Context context){}
    public static final MapUtils getInstance(Context context) {
        LazyHolder.context = context;
        return LazyHolder.INSTANCE;
    }
}  

二、饿汉式单例模式

//饿汉式单例类.在类初始化时,已经自行实例化

public class MapUtils {  
    private MapUtils() {}  
    private static final MapUtils instance = new MapUtils();  
    //静态工厂方法   
    public static MapUtils getInstance() {  
        return instance;  
    }  
}  

饿汉式在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的。 还有一种登记式单例模式.没有细细去看就不做介绍了.


什么是线程安全? 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。 或者说:一个类或者程序所提供的接口对于线程来说是原子操作,或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题,那就是线程安全的。


PS:对于设计模式我只是作为学习笔记来写的,并非网上大牛们的手笔,所以各位看官看看就行,有错误请多多指正,要真正学习设计模式,书籍有,《大话设计模式》,这个需要C++语言底子,《您的设计模式》这个讲解的很有风趣,没有《大话设计模式》讲解的深,还有一本《Head First 设计模式》也讲解的蛮有意思的。

© 著作权归作者所有

SunnyTime

SunnyTime

粉丝 6
博文 27
码字总数 17058
作品 0
静安
程序员
私信 提问
【设计模式笔记】(十六)- 代理模式

一、简述 代理模式(Proxy Pattern),为其他对象提供一个代理,并由代理对象控制原有对象的引用;也称为委托模式。 其实代理模式无论是在日常开发还是设计模式中,基本随处可见,中介者模式中...

MrTrying
2018/06/24
0
0
《PHP设计模式大全》系列分享专栏

《PHP设计模式大全》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页...

kaixin_code
2018/11/06
192
0
设计模式梳理(一)

设计模式梳理(一) 总体来说设计模式分为三大类: @案例源码地址:https://gitlab.com/lxqxsyu/DisgnPattern 创建型模式 简单工厂模式 工厂类是整个模式的关键。它包含必要的判断逻辑,能够...

lxq_xsyu
2017/11/02
0
0
JavaScript 的一些设计模式

设计模式的定义:在面向对象软件设计过程中针对特定问题的简洁而优雅的解决方案 设计模式是前人解决某个特定场景下对而总结出来的一些解决方案。可能刚开始接触编程还没有什么经验的时候,会...

格西南
08/20
0
0
《JavaScript设计模式与开发实践》原则篇(2)—— 最少知识原则

最少知识原则(LKP)说的是一个软件实体应当尽可能少地与其他实体发生相互作用。这 里的软件实体是一个广义的概念,不仅包括对象,还包括系统、类、模块、函数、变量等。 单一职责原则指导我们...

嗨呀豆豆呢
2018/12/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

02.日志系统:一条SQL更新语句是如何执行的?

我们还是从一个表的一条更新语句说起,我们创建下面一张表: create table T(ID int primary key, c int); 如果要将ID=2这一行c的值加1,SQL可以这么写: update T set c=c+1 where ID=2; 前...

scgaopan
48分钟前
7
0
【五分钟系列】掌握vscode调试技巧

调试前端js 准备一个前端项目 index.html <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1......

aoping
48分钟前
4
0
PhotoShop 高级应用:USM锐化/S锐化/防抖

、 高反差锐化+混合模式:叠加模式 【将更多的边缘细节添加到图像中】

东方墨天
59分钟前
7
0
Python数据可视化之matplotlib

常用模块导入 import numpy as npimport matplotlibimport matplotlib.mlab as mlabimport matplotlib.pyplot as pltimport matplotlib.font_manager as fmfrom mpl_toolkits.mplot3d i......

松鼠大帝
昨天
5
0
我用Bash编写了一个扫雷游戏

我在编程教学方面不是专家,但当我想更好掌握某一样东西时,会试着找出让自己乐在其中的方法。比方说,当我想在 shell 编程方面更进一步时,我决定用 Bash 编写一个扫雷游戏来加以练习。 我在...

老孟的Linux私房菜
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部