Java设计模式之单件模式深入讲解

 更新时间:2021年11月08日 16:18:14   作者:不侠居  
有人说单件模式是最简单的模式,因为它只有一个类,但其实它还有一些值得注意的地方,就如:出现并发性时,单件可能已经不是单件了

定义

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

Java单件模式

经典单件模式的实现

public class Singleton{
	private static Singleton uniqueInstance; // 利用一个静态变量来记录Singleton类的唯一实例
	private Singleton(){} // 把构造器声明为私有的,只有自Singleton类内才可以调用构造器
	// 用getInstance()方法实例化对象,并返回这个实例
	public static Singleton getInstance(){
		if (uniqueInstance == null){
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}
}

在多线程中以上代码会生成多个实例,所以需要我们对代码进行改进

多线程单件模式的实现

public  class Singleton{
	private static Singleton uniqueInstance;

	private Singleton(){}

	public static synchronized Singleton getInstance(){
		if(uniqueInstance == null){
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}
}

通过增加synchronized关键字到getInstance()方法中,我们迫使每个线程在进入这个方法之前,要先等候别的线程离开该方法。也就是说,不会有两个线程可以同时进入这个方法。

急切创建实例

public class Singleton{
	// 在静态初始化器(static initializai)中创建单件。这样可以保证线程安全(thread sate)
	private static Singleton uniqueInstance = new Singleton();

	private static Singleton getInstance(){
		return uniqueInstance;
	}
	
}

在JVM在加载这个类时马上创建此唯一的单件实例。JVM保证在任何线程访问uniqueInstance静态变量之前,一定创建此实例。

双重检查加锁

会有两次检查实例是否存在,若不存在则创建实例,若存在则返回

public class Singlenton{
	// volatile关键词:当uniqueInstance变量被初始化成Singleton实例时,多个线程正确地处理uniqueInstance变量
	private volatile static Singleton uniqueInstance();
	
	private Singleton(){}

	public static Singleton getInstance(){
		// 检查实例,如果不存在,就进入同步区块
		if(uniqueInstance == null){
			// 进入区块后,再检查一次。如果仍是null,才创建实例
			synchronized (Singleton.class){
				if(uniqueInstance == null){
					uniqueInstance = new Singleton();
				}
			}
		}
		return uniqueInstance;
	}
}

Python单件模式

模块实现

Python 的模块就是天然的单件模式,在模块第一次被导入时,会生成.pyc文件,之后再次导入时,就会直接加载之前生成的.pyc文件,不会再次执行模块代码
先创建一个Singleton文件

class Singleton:
	def getSingleton:
		pass
singleton = Singleton()

在其他文件中导入这个模块,这个类的地址是唯一的

new关键字实现

当实例化一个对象时,先调用类的__new__方法 ,默认调用的是父类Object.__new__方法,实例化对象。然后再调用类的__init__方法进行属性的初始化。
我们可以再__new__方法内加一个判断,若实例存在,则不实例化,若不存在,则实例化。

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = object.__new__(cls, *args, **kwargs)
        return cls._instance
    def __init__(self):
        pass

装饰器实现

通过装饰器来实现单件模式

函数装饰器

def singleton(cls):
	# 创建一个私有变量,类型为字典,用来存放类地址的
    _instance = {}

    def inner():
    	# 如果类不存在
        if cls not in _instance:
        	# 实例化一个类并存放在字典里
            _instance[cls] = cls()
        return _instance[cls]
    return inner
    
@singleton
class ClassName(object):
    def __init__(self):
        pass

类装饰器

class Singleton(object):
    def __init__(self, cls):
        self._cls = cls # 接受类名
        self._instance = {} # 存放类地址
    def __call__(self):
        if self._cls not in self._instance:
        	# 实例化类并存放在字典内
            self._instance[self._cls] = self._cls()
        return self._instance[self._cls]

@Singleton
class ClassName(object):
    def __init__(self):
        pass

以上就是Java设计模式之单件模式深入讲解的详细内容,更多关于Java设计模式的资料请关注脚本之家其它相关文章!

相关文章

  • Spring Boot文件上传原理与实现详解

    Spring Boot文件上传原理与实现详解

    这篇文章主要介绍了Spring Boot 文件上传原理与实现详解,前端文件上传是面向多用户的,多用户之间可能存在上传同一个名称、类型的文件;为了避免文件冲突导致的覆盖问题这些应该在后台进行解决,需要的朋友可以参考下
    2024-01-01
  • Java实现文件上传下载以及查看功能

    Java实现文件上传下载以及查看功能

    这篇文章主要为大家详细介绍了java如何实现文件上传和下载以及查看功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Java应用CPU使用率过高排查方式

    Java应用CPU使用率过高排查方式

    这篇文章主要介绍了Java应用CPU使用率过高排查方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • java并发编程JUC CountDownLatch线程同步

    java并发编程JUC CountDownLatch线程同步

    这篇文章主要介绍CountDownLatch是什么、CountDownLatch 如何工作、CountDownLatch 的代码例子来展开对java并发编程JUC CountDownLatch线程同步,需要的朋友可以参考下面文章内容
    2021-09-09
  • Java实战之酒店人事管理系统的实现

    Java实战之酒店人事管理系统的实现

    这篇文章主要介绍了如何用Java实现酒店人事管理系统,文中采用的技术有:JSP、Spring、SpringMVC、MyBatis等,感兴趣的小伙伴可以学习一下
    2022-03-03
  • SpringBoot动态生成接口实现流程示例讲解

    SpringBoot动态生成接口实现流程示例讲解

    最近遇到一个需求,需要在程序运行过程中,可以动态新增接口,自定义接口参数名称,基本类型,以及请求方法,请求头等等。通过几天的研究,找到了我需要的解决方案
    2023-01-01
  • SpringBoot集成Redisson操作Redis的实现方法

    SpringBoot集成Redisson操作Redis的实现方法

    Redisson是一个用于Java的Redis客户端,它提供了在分布式环境下操作Redis数据库的简单、高效的方式,本文主要介绍了SpringBoot集成Redisson操作Redis的实现方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • mybatis输出SQL格式化方式

    mybatis输出SQL格式化方式

    这篇文章主要介绍了mybatis输出SQL格式化方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • springboot2.x使用Jsoup防XSS攻击的实现

    springboot2.x使用Jsoup防XSS攻击的实现

    这篇文章主要介绍了springboot2.x使用Jsoup防XSS攻击的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • Java中getResourceAsStream用法分析

    Java中getResourceAsStream用法分析

    这篇文章主要介绍了Java中getResourceAsStream用法,较为详细的分析了getResourceAsStream的功能及用法,需要的朋友可以参考下
    2015-06-06

最新评论