摘要:總結(jié)中針對數(shù)組的訪問和賦值的意義應(yīng)該是在于越過對數(shù)組操作的包裝,進而達到優(yōu)化性能的目的。以上為拋磚引玉。。參考鏈接知乎請問數(shù)組的行為是如何實現(xiàn)的
在學(xué)習(xí)ConcurrentHashMap時發(fā)現(xiàn),源碼中對table數(shù)組的元素進行操作時,使用了三個封裝好的原子操作方法,如下:
/* ---------------- Table element access -------------- */ /* * Atomic access methods are used for table elements as well as * elements of in-progress next table while resizing. All uses of * the tab arguments must be null checked by callers. All callers * also paranoically precheck that tab"s length is not zero (or an * equivalent check), thus ensuring that any index argument taking * the form of a hash value anded with (length - 1) is a valid * index. Note that, to be correct wrt arbitrary concurrency * errors by users, these checks must operate on local variables, * which accounts for some odd-looking inline assignments below. * Note that calls to setTabAt always occur within locked regions, * and so require only release ordering. */ @SuppressWarnings("unchecked") static finalNode tabAt(Node [] tab, int i) { return (Node )U.getObjectAcquire(tab, ((long)i << ASHIFT) + ABASE); } static final boolean casTabAt(Node [] tab, int i, Node c, Node v) { return U.compareAndSetObject(tab, ((long)i << ASHIFT) + ABASE, c, v); } static final void setTabAt(Node [] tab, int i, Node v) { U.putObjectRelease(tab, ((long)i << ASHIFT) + ABASE, v); }
casTabAt這個方法我們可以很清晰地明白它封裝了對于數(shù)組元素的cas操作,但是另外兩個方法的意義如何理解呢?
源碼的作者使用Unsafe直接通過數(shù)組內(nèi)存地址以及索引偏移量去訪問和修改數(shù)組元素的值,和我們直接使用java代碼訪問(arr[i])、賦值(arr[i] = x )有什么區(qū)別呢?
請教了成哥(同事)后得到了一個重要的點:數(shù)組越界異常ArrayIndexOutOfBoundsException
如果java中的數(shù)組和c一樣,僅僅是一個指針的話,那么也許通過arr[i]訪問和通過內(nèi)存地址訪問不會有什么區(qū)別,但是由于ArrayIndexOutOfBoundsException這個眾所周知的異常,我們可以推斷:java中的數(shù)組是經(jīng)過了包裝的
另一個可以從側(cè)面印證的點是arr.length
大概搜索了一下了解到以下的知識(不保證正確):
jvm會為數(shù)組對象動態(tài)創(chuàng)建Class類文件,其標識為[
(HotSpot VM中)java對象的對象頭(Object header)內(nèi)會有一段用于記錄數(shù)組長度的數(shù)據(jù)
不敢再深挖了,感覺是個大坑。。
總結(jié):ConcurrentHashMap中針對table數(shù)組的Unsafe訪問和賦值的意義應(yīng)該是在于越過jvm對數(shù)組操作的包裝,進而達到優(yōu)化性能的目的。
以上為拋磚引玉。。
參考鏈接:
知乎-請問Java數(shù)組的length行為是如何實現(xiàn)的?
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74339.html
摘要:那么,如果之后不是簡單的操作,而是還有其它業(yè)務(wù)操作,之后才是,比如下面這樣,這該怎么辦呢其它業(yè)務(wù)操作這時候就沒辦法使用提供的方法了,只能業(yè)務(wù)自己來保證線程安全了,比如下面這樣其它業(yè)務(wù)操作這樣雖然不太友好,但是最起碼能保證業(yè)務(wù)邏輯是正確的。 刪除元素 刪除元素跟添加元素一樣,都是先找到元素所在的桶,然后采用分段鎖的思想鎖住整個桶,再進行操作。 public V remove(Objec...
摘要:原因是它支持多線程進行擴容操作,而并沒有加鎖。多線程的情況下如果一個或多個線程正在對進行擴容操作,當前線程也要進入擴容的操作中。 KillCode系列 -- Java篇 原文發(fā)布在我的個人博客中killCode 因為JDK1.8 與 1.7 里對ConcurrentHashMap 有很多不同的更改以提高性能。所以特別找出類似的方面,進行分析。 1. 內(nèi)部參數(shù) //初始容積為 16 p...
摘要:一擴容的基本思路中,最復(fù)雜的部分就是擴容數(shù)據(jù)遷移,涉及多線程的合作和。單線程注意這兩種情況都是調(diào)用了方法,通過第二個入?yún)⑦M行區(qū)分表示擴容后的新數(shù)組,如果為,表示首次發(fā)起擴容。第二種情況下,是通過和移位運算來保證僅有一個線程能發(fā)起擴容。 showImg(https://segmentfault.com/img/bVbf0J0?w=1000&h=663); 本文首發(fā)于一世流云專欄:http...
摘要:上一篇文章已經(jīng)就進行了部分說明,介紹了其中涉及的常量和變量的含義,有些部分需要結(jié)合方法源碼來理解,今天這篇文章就繼續(xù)講解并發(fā)前言本文主要介紹中的一些重要方法,結(jié)合上篇文章中的講解部分進行更進一步的介紹回顧下上篇文章,我們應(yīng)該已經(jīng)知道的整體結(jié) 上一篇文章已經(jīng)就ConcurrentHashMap進行了部分說明,介紹了其中涉及的常量和變量的含義,有些部分需要結(jié)合方法源碼來理解,今天這篇文章就...
摘要:最近準備面試,一談到基礎(chǔ),大部分面試官上來就數(shù)據(jù)結(jié)構(gòu)素質(zhì)三連與區(qū)別,底層數(shù)據(jù)結(jié)構(gòu),為什么能保證線程安全。數(shù)組順序存儲,內(nèi)存連續(xù),查詢快,插入刪除效率稍微低,不過現(xiàn)在略有改善。而在開始,是由和的方式去實現(xiàn)高并發(fā)下的線程安全。 最近準備面試,一談到j(luò)ava基礎(chǔ),大部分面試官上來就java數(shù)據(jù)結(jié)構(gòu)素質(zhì)三連:ArrayList與LinkedList區(qū)別,HashMap底層數(shù)據(jù)結(jié)構(gòu),Concur...
閱讀 1020·2021-10-27 14:15
閱讀 2775·2021-10-25 09:45
閱讀 1940·2021-09-02 09:45
閱讀 3366·2019-08-30 15:55
閱讀 1806·2019-08-29 16:05
閱讀 3202·2019-08-28 18:13
閱讀 3116·2019-08-26 13:58
閱讀 454·2019-08-26 12:01