设计模式之单例模式

Jimmy Lee

学习思考|May 10, 2015|Last edited: 2022-7-21|
type
Post
status
Published
date
May 10, 2015
slug
singleton
summary
单例模式有什么用处?有些对象其实我们只需要一个,比方说:线程池,缓存,对话框,注册表,日志对象...如果制造出多个实例,就会导致许多问题产生,例如程序的行为异常,资源使用过量,数据不一致
tags
设计模式
category
学习思考
icon
Update time
Jul 21, 2022 01:40 AM
Internal status
password

有什么用处

有些对象其实我们只需要一个,比方说:线程池,缓存,对话框,注册表,日志对象...如果制造出多个实例,就会导致许多问题产生,例如程序的行为异常,资源使用过量,数据不一致

如何做

利用静态类变量,静态方法和适当的访问修饰符

定义

单例模式,确保一个类只有一个实例,并提供一个全局访问点

注意点,多线程中使用单例

如果有多个线程同时调用getInstance(),可能会产生多个实例,那就用synchronized(同步)关键字修饰 但是同步会降低性能,实际上也就第一次getInstance()时需要考虑同步问题,之后就没有同步问题.

1.如果getInstance()的性能对应用程序不是很关键,就加上synchronized关键字

/** * 单例模式之懒汉模式 * 优点:在需要实例的时候才进行第一次实例化,在资源紧缺的时候,可以减少不必要的资源消耗 * 缺点:同步了getInstance(),会造成性能浪费 */publicclassSingletonLazy { /** * 利用一个静态变量来记录Singleton类的唯一实例 */privatestatic SingletonLazy instance; /** * 构造器声明为私有的,只有自己Singleton类才可以调用构造器 */privateSingletonLazy() { } /** * 用getInstance()实例化对象,并返回这个实例 * 在多线程中必须使用synchronized关键字修饰 * @return */publicstatic synchronized SingletonLazygetInstance() { //懒汉模式//如果未被实例化,则newif (instance ==null) { instance =new SingletonLazy(); } //如果已经实例化,则返回实例return instance; } }

2.如果getInstance()的性能对应用程序很关键,那就使用饿汉模式

使用饿汉模式
publicclassSingletonLazy{ //在静态初始化器(static initialize)中创建单例.这段代码保证了线程安全(Thread Safe)privatestatic SingletonLazy instance=new SingletonLazy(); privateSingletonLazy(){ } publicstatic SingletonLazygetInstance(){ //到这里,一定存在实例了,直接使用它return instance; } }

3.使用"双重检查锁"(double-checked locking),在getInstance()中减少使用同步

/** * 单例模式之使用"双重检查加锁" * 过程:在getInstance()中进行双重检查,确保一个实例 * 优点:在getInstance()中减少同步,增强性能,可以在多线程中使用 * 缺点:暂无 */publicclassSingletonDoubleCheckedLocking { /** * 利用一个静态变量来记录Singleton类的唯一实例 * volatile关键字确保:当instance变量被初始化为Singleton实例时,多个线程正确地处理instance变量 */privatestaticvolatile SingletonDoubleCheckedLocking instance; /** * 构造器声明为私有的,只有自己Singleton类才可以调用构造器 */privateSingletonDoubleCheckedLocking() { } /** * 用getInstance()实例化对象,并返回这个实例 * 方法不必用synchronized关键字修饰 * @return */publicstatic SingletonDoubleCheckedLockinggetInstance() { if(instance==null){//检查实例,如果不存在,则进入同步区块//注意:只有第一次调用getInstance()方法才彻底执行这里的代码 synchronized (SingletonDoubleCheckedLocking.class){ if(instance==null){//进入区块后,再检查一次,如果是null,才创建实例 instance=new SingletonDoubleCheckedLocking(); } } } return instance; } }

项目地址

java设计模式实现 如果觉得有点收获,记得在项目上点star哦!

开始订阅我的关于终生学习, 生产力以及知识管理的文章. 订阅后, 您将收到我的精选文章.

©2014-2024 Jimmy Lee. All rights reserved. 公众号: 技术管理方法论
Powered By My Lovely Children