关键词:
在上一篇文章 单例模式(上)—-如何优雅地保证线程安全问题中,我们采取了懒汉式写法来写我们的单例模式,并且重点讲解了懒汉式中线程安全的问题。这篇我们来讲讲单例模式中的其他几种写法。
上篇文章中,方法和变量的声明都忘了加上“static”的声明,这里提醒一下。
懒汉式
懒汉式在上节我们已经讲过了,直接给出代码:
public class Singleton
private static volatile Singleton instance = null;
private Singleton();
public static Singleton getInstance()
if (instance == null)
synchronized (Singleton.class)
if (instance == null)
instance = new Singleton();
return instance;
懒汉式这种方式需要我们来自己加锁,保证线程安全的问题。
不过就算我们保证了线程安全,这种写法还是无法保证存在唯一一个对象实例。因为别人还是可以通过反射的方式来创建一个新的对象。我写个示例:
public class Singleton
public static void main(String[] args) throws Exception
//获得构造器
Constructor<Singleton> c = Singleton.class.getDeclaredConstructor();
//把构造器设置为可访问
c.setAccessible(true);
//创建两个实例对象
Singleton s1 = c.newInstance();
Singleton s2 = c.newInstance();
//比较下两个实例是否相等
System.out.println(s1 == s2);
打印结果:false。
所以懒汉式这种方式还是存在一些缺点的。
饿汉式
所谓饿汉式,就是一开始把对象实例创建出来,而不是等getInstance这个方法被调用才来创建对象。代码如下:
public class Singleton2
private static Singleton2 instance = new Singleton2();
//私有构造器
private Singleton2();
public static Singleton2 getInstance()
return instance;
饿汉式与懒汉式相比,我们不用管线程安全的问题,代码看起来也比较简洁。
但是,由于对象一开始就被创建出来了,假如我们从头到尾都不调用getInstance()这个方法,那么这个对象就白创建了。
当然,和懒汉式一样,饿汉式也存在反射问题。
总结一下饿汉式的一些问题:
1、有可能出现对象白白浪费的情况。
2、和懒汉式一样,无法组织反射问题。
采用静态内部类的写法
直接上代码
public class Singleton3
//静态内部类
private static class LazyHolder
private static Singleton3 instance = new Singleton3();
//私有构造器
private Singleton3();
public static Singleton3 getInstance()
return LazyHolder.instance;
由于外部类无法访问静态内部类,因此只有当外部类调用Singleton.getInstance()方法的时候,才能得到instance实例。
并且,instance实例对象初始化的时机并不是在Singleton被加载的时候,而是当getInstance()方法被调用的时候,静态内部类才会被加载,这时instance对象才会被初始化。并且也是线程安全的。
所以,与饿汉式相比,通过静态内部类的方式,可以保证instance实例对象不会被白白浪费。
但是,它仍然存在反射问题。
采取枚举的方式
直接上代码:
public enum Singleton4
//一般用大写的了,不过为了和前面的统一
//我就用小写的了
instance;
枚举的方式简单吧?一行代码就搞定了,不过和饿汉式一样,由于一开始instance实例就被创建了,所以有可能出现白白浪费的情况。
但是,通过枚举的方式,不仅代码简单,线程安全,而且JVM还能阻止反射获取枚举类的私有构造器。
下面做个实验
public enum Singleton4
//一般用大写的了,不过为了和前面的统一
//我就用小写的了
instance;
public static void main(String[] args) throws Exception
//获得构造器
Constructor<Singleton4> c = Singleton4.class.getDeclaredConstructor();
//把构造器设置为可访问
c.setAccessible(true);
//创建两个实例对象
Singleton4 s1 = c.newInstance();
Singleton4 s2 = c.newInstance();
//比较下两个实例是否相等
System.out.println(s1 == s2);
结果出现了异常:
Exception in thread “main” java.lang.NoSuchMethodException: singleton.Singleton4.()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at singleton.Singleton4.main(Singleton4.java:12)
所以,这种枚举的方式可以说的用的最多的一种方式了,唯一的缺点就是对象一开始就被创建,可能出现白白浪费没有用到对象的情况。
不过,总体上,还是推荐采用枚举的方式来写。
完
获取更多原创文章,可以关注下我的公众号:苦逼的码农,我会不定期分享一些资源和软件等。后台回复礼包送你一份时下热门的资源大礼包。同时也感谢把文章介绍给更多需要的人。
单例模式的几种写法的差异
设计模式:单例模式的几种写法的差异1.单例模式的概念单例模式(SingletonPattern)是Java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类... 查看详情
常见的几种单例模式写法(代码片段)
单例模式:是一种常用的软件设计模式,在它的核心结构中值包含一个被称为单例的特殊类。一个类只有一个实例,即一个类只有一个对象实例。 对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以... 查看详情
单例模式的几种写法
1、静态初始化/**饿汉式类加载到内存后,就实例化一个单例,jvm保证线程安全简单实用,推荐使用唯一缺点:不管用到与否,类加载时就完成实例化(话说你不用的,你转载它干啥)一般这种就够用了*/publicclassMgr01{privatestaticfin... 查看详情
单例模式的几种写法
1首先要知道,什么叫做单例模式。单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例2单例模式简介单例模... 查看详情
java单例模式常见的几种写法(代码片段)
单例模式有多种写法,都有各自的优缺点,最常见的优缺点就是【懒汉和饿汉】的比较,以及是否线程安全懒汉模式,节约内存,只有使用到时才创建单例对象,可能会有线程安全问题饿汉模式,浪费... 查看详情
单例模式的几种写法
饿汉式单例类public class Singleton { private Singleton(){ } &nb 查看详情
javase面试题——singleton单例模式的几种写法(代码片段)
...ff01;!!我们都知道,在23种设计模式中,单例模式是最容易理解、最简单的一种了,它也是软件开发中最常用的设计模式之一了。单例设计模式,即某个类在整个系统中只能有一个实例对象可被获取和使... 查看详情
java设计模式——单例设计模式(代码片段)
我们一般在学习的第一个设计模式都是单例设计模式,因为单例设计模式广泛的应用在我们程序开发中。今天就和大家简单的聊一聊单例设计模式,因为在我们刚开始学习Java基础时,就了解了单例,有的同学在学... 查看详情
单例模式的几种写法(代码片段)
...态变量保存8*(3)向外提供这个实例9*(4)强调这是一个单例,用static关键字修饰10*/11publicclassSingleton112publicstaticfinalSingleton1INSTANCE=newSingleton1();1314privateSingleton1()151617也可以采用枚举类的方式1packagesingle;23/**4*使用枚举的方式设计... 查看详情
聊一聊spring在单例模式下的线程安全
点击关注公众号,实用技术文章及时了解来源:blog.csdn.net/fuzhongmin05/article/details/1008498671、有状态的bean与无状态的bean有状态bean:每个用户有自己特有的一个实例,在用户的生存期内,bean保存了用户的信息ÿ... 查看详情
单例模式的几种实现方式
单例模式的定义: 保证一个类仅有一个实例,并提供一个它的全局访问点。 单例模式有两种实现方式:饿汉模式和懒汉模式。懒汉式实现代码:publicclassSingleton privatestaticSingletonuniqueInstance=null; private Singleton()... 查看详情
关于单利模式的几种实现方式(代码片段)
单例模式是java中非常常见的一种设计模式,也是java学习中很热门的一个知识模块,今天就和大家一起来了解一下单例模式和单例模式的几种实现方式。 单例模式的定义: 单例模式是指某个类只有一个实例,并... 查看详情
常见的几种单例模式(代码片段)
单例模式:是一种常用的软件设计模式,在它的核心结构中值包含一个被称为单例的特殊类。一个类只有一个实例,即一个类只有一个对象实例。 对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以... 查看详情
100个unity小知识点|unity中常用的几种单例写法(代码片段)
...来专业制作游戏!Unity小知识点学习Unity中常用的几种单例写法单例模式(SingletonPattern)保证一个类仅有一个实例,并提供一个访问它的全局访问点单例模式优点单例模式核心在于对于某个单例类,在系统中同时只存在... 查看详情
100个unity小知识点|unity中常用的几种单例写法(代码片段)
...来专业制作游戏!Unity小知识点学习Unity中常用的几种单例写法单例模式(SingletonPattern)保证一个类仅有一个实例,并提供一个访问它的全局访问点单例模式优点单例模式核心在于对于某个单例类,在系统中同时只存在... 查看详情
python常用的几种设计模式是啥
python常用的几种设计模式有:1、单例模式,确保某一个类只有一个实例;2、工厂模式,使用一个公共的接口来创建对象;3、策略模式,随着策python常用的几种设计模式有:1、单例模式,确保某一个类只有一个实例;2、工厂模... 查看详情
实现单例模式的几种方式(代码片段)
import 是Python中的天然单例模式,我最先推荐这种方式。 创建两个文件 signletion.py signletion_import.py,文件内容如下classUser():def__new__(cls,*args,**kw):print("newinstance")returnsuper().__new__(cls,*args,**kw)defg 查看详情
单例模式几种写法
第一种(懒汉,线程不安全): Java代码 public class Singleton { private static Singleton instance; pr 查看详情