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)

相关推荐

  • 红烧肉的做法窍门,红烧肉不发柴的窍门是什么

    技术红烧肉的做法窍门,红烧肉不发柴的窍门是什么红烧肉色泽红润、皮软肉嫩、口口诱人红烧肉的做法窍门,搭配米饭,幸福感满满。作为一名厨子,我认为红烧肉不存在发柴的现象,除非是在选肉、封边锁水、锅具选择这三个环节出错,否则红烧

    生活 2021年10月22日
  • 荸荠怎么煮,朋友送了好多马蹄怎么做菜

    技术荸荠怎么煮,朋友送了好多马蹄怎么做菜原料主料荸荠怎么煮:马蹄9个 梨1个 橘子1个 辅料:水适量调料:冰糖适量 详细步骤 1、将马蹄,梨,橘子洗好。
    2、马蹄梨削皮,橘子剥皮。
    3、将马蹄,梨切小块,锅中放水烧开

    生活 2021年10月25日
  • 香港多少平方公里,香港的总面积是多少平方公里

    技术香港多少平方公里,香港的总面积是多少平方公里香港的总面积香港多少平方公里:1104.43平方公里。 香港(英文:HongKong;普通话:xiānggǎng;缩写:HK),简称“港”,全称为中华人民共和国香港特别行政

    生活 2021年10月22日
  • Spring Cloud微服务的概念是什么

    技术Spring Cloud微服务的概念是什么本篇文章为大家展示了Spring Cloud微服务的概念是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。单体架构简介在软件设计中

    攻略 2021年12月2日
  • 怎么理解java图的对象化描述

    技术怎么理解java图的对象化描述这篇文章主要讲解了“怎么理解java图的对象化描述”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么理解java图的对象化描述”吧!一、

    攻略 2021年11月9日
  • PLSQL Developer试用期到了怎么办

    技术PLSQL Developer试用期到了怎么办这篇文章给大家分享的是有关PLSQL Developer试用期到了怎么办的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。PLSQL Develo

    攻略 2021年11月24日