java枚舉是怎么保證線程安全的-創(chuàng)新互聯(lián)

本篇內(nèi)容介紹了“java枚舉是怎么保證線程安全的”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

成都網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁(yè)設(shè)計(jì)、重慶網(wǎng)站建設(shè)、微信開(kāi)發(fā)、微信平臺(tái)小程序開(kāi)發(fā)、集團(tuán)成都企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。核心團(tuán)隊(duì)均擁有互聯(lián)網(wǎng)行業(yè)多年經(jīng)驗(yàn),服務(wù)眾多知名企業(yè)客戶;涵蓋的客戶類型包括:成都軟裝設(shè)計(jì)等眾多領(lǐng)域,積累了大量豐富的經(jīng)驗(yàn),同時(shí)也獲得了客戶的一致贊許!

枚舉是如何保證線程安全的

要想看源碼,首先得有一個(gè)類吧,那么枚舉類型到底是什么類呢?是enum嗎?答案很明顯不是,enum就和class一樣,只是一個(gè)關(guān)鍵字,他并不是一個(gè)類,那么枚舉是由什么類維護(hù)的呢,我們簡(jiǎn)單的寫(xiě)一個(gè)枚舉:

public enum t {SPRING,SUMMER,AUTUMN,WINTER;}

然后我們使用反編譯,看看這段代碼到底是怎么實(shí)現(xiàn)的,反編譯(Java的反編譯)后代碼內(nèi)容如下:

public final class T extends Enum{private T(String s, int i){super(s, i);}public static T[] values(){T at[];int i;T at1[];System.arraycopy(at = ENUM$VALUES, 0, at1 = new T[i = at.length], 0, i);return at1;}public static T valueOf(String s){return (T)Enum.valueOf(demo/T, s);}public static final T SPRING;public static final T SUMMER;public static final T AUTUMN;public static final T WINTER;private static final T ENUM$VALUES[];static{SPRING = new T("SPRING", 0);SUMMER = new T("SUMMER", 1);AUTUMN = new T("AUTUMN", 2);WINTER = new T("WINTER", 3);ENUM$VALUES = (new T[] {SPRING, SUMMER, AUTUMN, WINTER});}}

通過(guò)反編譯后代碼我們可以看到,public final class T extends Enum,說(shuō)明,該類是繼承了Enum類的,同時(shí)final關(guān)鍵字告訴我們,這個(gè)類也是不能被繼承的。當(dāng)我們使用enmu來(lái)定義一個(gè)枚舉類型的時(shí)候,編譯器會(huì)自動(dòng)幫我們創(chuàng)建一個(gè)final類型的類繼承Enum類,所以枚舉類型不能被繼承,我們看到這個(gè)類中有幾個(gè)屬性和方法。

我們可以看到:

public static final T SPRING;public static final T SUMMER;public static final T AUTUMN;public static final T WINTER;private static final T ENUM$VALUES[];static{SPRING = new T("SPRING", 0);SUMMER = new T("SUMMER", 1);AUTUMN = new T("AUTUMN", 2);WINTER = new T("WINTER", 3);ENUM$VALUES = (new T[] {SPRING, SUMMER, AUTUMN, WINTER});}

都是static類型的,因?yàn)閟tatic類型的屬性會(huì)在類被加載之后被初始化,我們?cè)谏疃确治鯦ava的ClassLoader機(jī)制(源碼級(jí)別)和Java類的加載、鏈接和初始化兩個(gè)文章中分別介紹過(guò),當(dāng)一個(gè)Java類第一次被真正使用到的時(shí)候靜態(tài)資源被初始化、Java類的加載和初始化過(guò)程都是線程安全的。所以,創(chuàng)建一個(gè)enum類型是線程安全的。

為什么用枚舉實(shí)現(xiàn)的單例是好的方式

在[轉(zhuǎn)+注]單例模式的七種寫(xiě)法中,我們看到一共有七種實(shí)現(xiàn)單例的方式,其中,Effective Java作者Josh Bloch 提倡使用枚舉的方式,既然大神說(shuō)這種方式好,那我們就要知道它為什么好?

1. 枚舉寫(xiě)法簡(jiǎn)單

寫(xiě)法簡(jiǎn)單這個(gè)大家看看[轉(zhuǎn)+注]單例模式的七種寫(xiě)法里面的實(shí)現(xiàn)就知道區(qū)別了。

public enum EasySingleton{INSTANCE;}

你可以通過(guò)EasySingleton.INSTANCE來(lái)訪問(wèn)。

2. 枚舉自己處理序列化

我們知道,以前的所有的單例模式都有一個(gè)比較大的問(wèn)題,就是一旦實(shí)現(xiàn)了Serializable接口之后,就不再是單例得了,因?yàn)?,每次調(diào)用 readObject()方法返回的都是一個(gè)新創(chuàng)建出來(lái)的對(duì)象,有一種解決辦法就是使用readResolve()方法來(lái)避免此事發(fā)生。

但是,**為了保證枚舉類型像Java規(guī)范中所說(shuō)的那樣,每一個(gè)枚舉類型極其定義的枚舉變量在JVM中都是的,在枚舉類型的序列化和反序列化上,Java做了特殊的規(guī)定。

在序列化的時(shí)候Java僅僅是將枚舉對(duì)象的name屬性輸出到結(jié)果中,反序列化的時(shí)候則是通過(guò)java.lang.Enum的valueOf方法來(lái)根據(jù)名字查找枚舉對(duì)象。

同時(shí),編譯器是不允許任何對(duì)這種序列化機(jī)制的定制的,因此禁用了writeObject、readObject、readObjectNoData、writeReplace和readResolve等方法。 我們看一下這個(gè)valueOf方法:

public static <T extends Enum<T>> T valueOf(Class<T> enumType,String name) { T result = enumType.enumConstantDirectory().get(name); if (result != null) return result; if (name == null) throw new NullPointerException("Name is null"); throw new IllegalArgumentException( "No enum const " + enumType +"." + name); }

從代碼中可以看到,代碼會(huì)嘗試從調(diào)用enumType這個(gè)Class對(duì)象的enumConstantDirectory()方法返回的map中獲取名字為name的枚舉對(duì)象,如果不存在就會(huì)拋出異常。

再進(jìn)一步跟到enumConstantDirectory()方法,就會(huì)發(fā)現(xiàn)到最后會(huì)以反射的方式調(diào)用enumType這個(gè)類型的values()靜態(tài)方法,也就是上面我們看到的編譯器為我們創(chuàng)建的那個(gè)方法,然后用返回結(jié)果填充enumType這個(gè)Class對(duì)象中的enumConstantDirectory屬性。

所以,JVM對(duì)序列化有保證。

3.枚舉實(shí)例創(chuàng)建是thread-safe(線程安全的)

當(dāng)一個(gè)Java類第一次被真正使用到的時(shí)候靜態(tài)資源被初始化、Java類的加載和初始化過(guò)程都是線程安全的。所以,創(chuàng)建一個(gè)enum類型是線程安全的。

“java枚舉是怎么保證線程安全的”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

網(wǎng)站欄目:java枚舉是怎么保證線程安全的-創(chuàng)新互聯(lián)
文章路徑:http://muchs.cn/article6/eeiog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)網(wǎng)站設(shè)計(jì)公司、Google、全網(wǎng)營(yíng)銷推廣、ChatGPT靜態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作