java枚举是怎么保证线程安全的

技术java枚举是怎么保证线程安全的本篇内容介绍了“java枚举是怎么保证线程安全的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够

本文介绍了关于“java枚举如何确保线程安全”的知识。很多人在实际案件操作中都会遇到这样的困难。接下来,让边肖带领大家学习如何应对这些情况!希望大家认真阅读,学点东西!

枚举是如何保证线程安全的

要想看到源代码,首先要有一个类,那么枚举类型是什么呢?是枚举吗?答案显然不是。enum只是一个关键字,就像class一样。它不是一个类。那么枚举由哪个类维护呢?让我们简单地写一个枚举:

公共枚举t {SPRING,SUMMER,FAULT,WINTER}

然后我们使用反编译来看看这段代码是如何实现的。反编译(Java的反编译)后,代码内容如下:

公共最终类T扩展了Enum {私有T(String s,int i){super(s,I)};}公共静态T[]值(){ T at[];int I;t at 1[];system . array copy(at=ENUM $ VALUES,0,at1=new T[i=at.length],0,I);在1点返回;}公共静态T值Of(字符串){return (T)Enum.valueOf(演示/T,s);}公共静态最终T SPRING公开静态决赛T SUMMER大众静态决赛T fault;公共静态决赛T WINTER私有静态最终T ENUM $ VALUES[];静态{SPRING=新T('SPRING ',0);SUMMER=新T('SUMMER ',1);秋=新T('秋',2);WINTER=新T('WINTER ',3);ENUM$VALUES=(new T[] {SPRING,SUMMER,秋,冬});}}

从反编译的代码中我们可以看到,公共最终类T扩展Enum表明这个类继承了Enum类,而final关键字告诉我们这个类也不能继承。当我们使用穆恩定义枚举类型时,编译器会自动帮助我们创建一个继承枚举类的最终类型类,因此枚举类型不能被继承。我们看到这个类中有几个属性和方法。

我们可以看到:

公共静态最终T SPRING公开静态决赛T SUMMER大众静态决赛T fault;公共静态决赛T WINTER私有静态最终T ENUM $ VALUES[];静态{SPRING=新T('SPRING ',0);SUMMER=新T('SUMMER ',1);秋=新T('秋',2);WINTER=新T('WINTER ',3);ENUM$VALUES=(new T[] {SPRING,SUMMER,秋,冬});}

它们都是静态类型的,因为静态类型的属性将在类加载后初始化。我们在两篇文章中分别介绍了对Java的类加载器机制(源代码级)和Java类加载、链接和初始化的深入分析。当一个Java类第一次实际使用时,静态资源被初始化,Java类的加载和初始化过程是线程安全的。因此,创建枚举类型是线程安全的。

为什么用枚举实现的单例是最好的方式

在[注] singleton pattern的七种编写方法中,我们可以看到实现singleton的方法有七种。其中,Effective Java作者Josh Bloch提倡使用枚举。既然大神说这种方式好,我们就要知道为什么好。

1. 枚举写法简单

简单的写作。让我们来看看singleton pattern的七种编写方法的实现,以了解它们之间的区别。

公共枚举EasySingleton { INSTANCE}

您可以通过EasySingleton访问它。情况

2. 枚举自己处理序列化

我们知道,以前所有的singleton模式都有一个很大的问题,那就是一旦实现了Serializable接口,它就不再是singleton了,因为对readObject()方法的每次调用都会返回一个新创建的对象,一种解决方案是使用readResolve()方法来避免这种情况。

但是,**为了保证Java规范中所述的枚举类型在JVM中是唯一的,Java对枚举类型的序列化和反序列化做了特殊的规定。

序列化时,Java只将枚举对象的name属性输出到结果中,而反序列化时,则使用java.lang.Enum的valueOf方法按名称查找枚举对象。

同时,编译器不允许对这种序列化机制进行任何自定义,因此禁用了writeObject、readObject、readObjectNoData、writeReplace readResolve等方法。让我们看看这个方法的价值:

公共静态T扩展了EnumT T valueOf(ClassT enumType,String name) { T结果=enum type . enumconstanntdirectory()。get(name);如果(结果!=null)返回结果;if (name==null)抛出新的NullPointerException('Name为null ');引发新的IllegalArgumentException('无枚举常量'枚举类型' '姓名);}

从代码中可以看到,代码将尝试通过调用Class对象enumType的enumConstantDirectory()方法从返回的映射中获取名为name的枚举对象,如果它不存在,将引发异常。

进一步遵循enumconstatdirectory()方法,你会发现最后会以反射的方式调用enumType静态值()方法,也就是我们上面看到的编译器为我们创建的方法,然后enumconstatdirectory对象中的enumconntdirectory属性会被返回的结果填充。

因此,JVM保证了序列化。

3.枚举实例创建是thread-safe(线程安全的)

当第一次实际使用Java类时,静态资源被初始化,加载和初始化Java类的过程是线程安全的。因此,创建枚举类型是线程安全的。

这里介绍一下“java枚举如何保证线程安全”的内容。感谢您的阅读。如果你想了解更多的行业,可以关注网站。边肖将为您输出更多高质量的实用文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/105117.html

(0)

相关推荐

  • Android如何在安卓上实现通用卡证识别

    技术Android如何在安卓上实现通用卡证识别这篇文章主要介绍“Android如何在安卓上实现通用卡证识别”,在日常操作中,相信很多人在Android如何在安卓上实现通用卡证识别问题上存在疑惑,小编查阅了各式资料,整理出

    攻略 2021年11月15日
  • oraclenumber型深度解析(oracle逻辑读是读哪里的数据)

    技术怎样浅析Oracle的物理读 逻辑读 一致性读 当前模式读怎样浅析Oracle的物理读 逻辑读 一致性读 当前模式读,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简

    攻略 2021年12月20日
  • View如何实现非中心点旋转

    技术View如何实现非中心点旋转这篇文章主要为大家展示了“View如何实现非中心点旋转”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“View如何实现非中心点旋转”这篇文章吧。

    攻略 2021年12月3日
  • 写字的拼音怎么写,写字的字的繁体字怎么写

    技术写字的拼音怎么写,写字的字的繁体字怎么写【繁体写法】写【本义】移置;放置。【基本字义】1、用笔作字。例如写字的拼音怎么写:写字、写作、编写。2、描摹,叙述。例如:写生、写实、写照。【常见组词】1、大写:汉字数目字的一

    生活 2021年10月20日
  • 如何深入理解Java虚拟机JVM类加载初始化

    技术如何深入理解Java虚拟机JVM类加载初始化如何深入理解Java虚拟机JVM类加载初始化,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1

    2021年11月21日
  • DM7 RAC数据库怎样恢复成单机数据库

    技术DM7 RAC数据库怎样恢复成单机数据库本篇文章为大家展示了DM7 RAC数据库怎样恢复成单机数据库,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。DM7 RAC数据库恢复成单

    攻略 2021年11月30日