博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单例模式(Singletion)
阅读量:6934 次
发布时间:2019-06-27

本文共 2501 字,大约阅读时间需要 8 分钟。

hot3.png

单例模式(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 设计模式》也讲解的蛮有意思的。

转载于:https://my.oschina.net/SunnyTime/blog/750225

你可能感兴趣的文章
js 变量、函数提升
查看>>
创新的前端 豆瓣书评 摘录
查看>>
(转)SpringBoot系列—Redis使用
查看>>
(Android 即时通讯) [悬赏],不管是谁发现一个漏洞奖励人民币1000元!
查看>>
百度开源其NLP主题模型工具包,文本分类等场景可直接使用L——LDA进行主题选择本质就是降维,然后用于推荐或者分类...
查看>>
Oracle11g创建表空间
查看>>
try~Catch语句中异常的处理过程
查看>>
贝塞尔曲线与CAShapeLayer的关系以及Stroke动画
查看>>
阅读《Android 从入门到精通》(29)——四大布局
查看>>
IT运维的定义
查看>>
Temporary ASP.Net Files探究
查看>>
CSDN开源夏令营 百度数据可视化实践 ECharts(8)
查看>>
poj 1284 Primitive Roots(原根+欧拉函数)
查看>>
OpenJudge百炼习题解答(C++)--题4010:2011
查看>>
Oracle PL/SQL语句基础学习笔记(上)
查看>>
MVC,MVP 和 MVVM 的图示
查看>>
正則表達式常见例题
查看>>
STM32 使用 FreeRTOS过程记录
查看>>
ASP.NET Core身份认证服务框架IdentityServer4(2)-整体介绍
查看>>
P1064 金明的预算方案
查看>>