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

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

单例模式的定义:

  • 确保一个类只有一个实例,该类负责创建自己的对象,同时确保只有单个对象被创建
  • 并且提供一个全局的访问点,外部通过这个访问点来访问该类的唯一实例,这里的全局实际上指的就是静态字段

那么我们为什么要用单例模式呢?

在我们系统中,有一些对象其实我们只需要一个,比如说:线程池、缓存、对话框等,事实上,这一类对象只能有一个实例,如果制造出多个实例就可能会导致一些问题的产生,比如:程序的行为异常、资源使用过量、或者不一致的结果,单例模式是为了避免重复生成同一实例对象而产生的一种模式

为什么不适用全局变量确保一个类只有一个实例呢

我们直到全局变量分为静态变量和实例变量,静态变量也可以保证该类的实例只存在一个,只要程序加载了类的字节码,不用创建任何实例对象,静态变量就会被分配空间,静态变量就可以被使用了。但是如果说这个对象非常消耗资源,而且在程序做某次执行中一直没用,这样就造成了资源的浪费,利用单例模式的话,我们就可以实现在需要使用的时候才创建对象,这样就避免了不必要的资源浪费

使用单例模式需要注意的关键点

单例模式的核心就是三私一公:

  1. 私有化的构造方法:避免在类外使用new class来创建对象实体,我们只允许使用我们设定好的公共方法来建立实体
  2. 私有化的克隆方法:避免在使用公共方法获取实例后,再通过clone的方法将对象实体克隆出新的对象
  3. 私有化的静态变量:这里存在两个问题:1. 为什么变量要设置成私有化, 2.为什么变量要设置成静态。首先我们先来解释第二个问题:因为在单例模式中,类的实例对象只能通过类内部的一个静态方法访问,静态方法只能访问静态变量,所以存储类实例的变量就必须是静态变量。那么为什么要设置成私有呢?其实最主要的原因就是防止外部修改该实例对象。因为这个变量是一个静态方法,那么就意味着可以通过类名的方式直接调用,如果不是私有的,那么外部就可以修改它
  4. 公共的静态方法:用于存储实例化的对象,供外界获取

单例模式的实现方法

1.饿汉式

饿汉单例在类加载过程中就实例化类对象,因此称为"饿汉",由于Java类加载的过程本身是线程安全的,因此饿汉式的优点是无需额外同步即线程安全,并发效率高,缺点是由于无法延迟加载,导致占用空间资源

public class singletonHungry {	private static SingletonHungry instance = new SingletonHungry();  //类初始化的时候立即加载对象	private SingletonHungry() {}  //私有构造方法,外部不能new	public static SingletonHungry getInstance() {		return instance;	}}

2.懒汉式

懒汉式单例模式在第一次调用getInstance方法时才实例化对象,因此属于延迟加载的实现方式。但是getInstance方法需要用synchronized关键字同步,会降低并发效率。如果不用synchronized关键字修饰getInstance方法,在多线程的条件下会出现实例化多个对象的情况

public class SingletonLazy {	private static SingletonLazy instance;  //注意这里的变量一开始只是声明,并没有实例化	private SingletonLazy() {}	public static synchronized SingletonLazy getInstance() {		if(instance==null) {			instance=new SingletonyLazy();  //调用getInstance方法后再实例化对象		}		return instance;	}}

3.双重加锁检查版本

利用双重检查加锁,首先检查是否实例已经创建,如果尚未创建,才进行同步,这样一来,只有一次同步

public class Singleton {	//volatile保证,当静态变量被初始化成实例时,多个线程可以正确处理	private volatitle static Singleton uniqueInstance;	private Singleton() {}	public static Singleton getInstance() {		//检查实例,如果不存在,就进入同步代码块		if(uniqueInstance == null) {			synchronized(Singleton.class) {			//进入同步代码块后,再检查一次,如果仍是null,才创建实例				if(uniqueInstance == null) {					uniqueInstance = new Singleton();				}			}		}		return uniqueInstance;	}}

转载地址:http://xhjmb.baihongyu.com/

你可能感兴趣的文章
假如从餐饮店的角度来看架构…
查看>>
这个充电宝太黑科技了,又小又不用自己带线,长见识了~
查看>>
HDC.2019后再发力,AppGallery Connect服务新升级
查看>>
网易云音乐热评的规律,44万条数据告诉你
查看>>
超神!GitHub 标星 5.5w,如何用 Python 实现所有算法?
查看>>
扛住100亿次请求——如何做一个“有把握”的春晚红包系统
查看>>
在北京看场雪为什么这么难?
查看>>
新年了,5G手机芯片,到底买谁?
查看>>
疫情之下「在家办公模式」开启,你该选择哪些远程协同工具?
查看>>
如何使用pdpipe与Pandas构建管道?
查看>>
远程办公的33种预测
查看>>
阿里巴巴架构师:十问业务中台和我的答案
查看>>
华为云发布三类六款计算实例 打造更强云端计算能力
查看>>
PHP 语言地位遭受挑战,PHP 程序员路在何方?
查看>>
PostgreSQL好评如潮,它是如何做到的?
查看>>
2017码云群英会,共享开源技术盛宴
查看>>
看完这份参会指南,Get 2017 OSC 年终盛典正确参会姿势!
查看>>
盛食厉兵 中科天玑挖掘大数据价值助力行业数字化转型
查看>>
白鹭引擎正式支持微信小游戏开发
查看>>
2018年,你所不知道的Jira!
查看>>