摘要:總結中針對數組的訪問和賦值的意義應該是在于越過對數組操作的包裝,進而達到優化性能的目的。以上為拋磚引玉。。參考鏈接知乎請問數組的行為是如何實現的
在學習ConcurrentHashMap時發現,源碼中對table數組的元素進行操作時,使用了三個封裝好的原子操作方法,如下:
/* ---------------- 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這個方法我們可以很清晰地明白它封裝了對于數組元素的cas操作,但是另外兩個方法的意義如何理解呢?
源碼的作者使用Unsafe直接通過數組內存地址以及索引偏移量去訪問和修改數組元素的值,和我們直接使用java代碼訪問(arr[i])、賦值(arr[i] = x )有什么區別呢?
請教了成哥(同事)后得到了一個重要的點:數組越界異常ArrayIndexOutOfBoundsException
如果java中的數組和c一樣,僅僅是一個指針的話,那么也許通過arr[i]訪問和通過內存地址訪問不會有什么區別,但是由于ArrayIndexOutOfBoundsException這個眾所周知的異常,我們可以推斷:java中的數組是經過了包裝的
另一個可以從側面印證的點是arr.length
大概搜索了一下了解到以下的知識(不保證正確):
jvm會為數組對象動態創建Class類文件,其標識為[
(HotSpot VM中)java對象的對象頭(Object header)內會有一段用于記錄數組長度的數據
不敢再深挖了,感覺是個大坑。。
總結:ConcurrentHashMap中針對table數組的Unsafe訪問和賦值的意義應該是在于越過jvm對數組操作的包裝,進而達到優化性能的目的。
以上為拋磚引玉。。
參考鏈接:
知乎-請問Java數組的length行為是如何實現的?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/74339.html
摘要:那么,如果之后不是簡單的操作,而是還有其它業務操作,之后才是,比如下面這樣,這該怎么辦呢其它業務操作這時候就沒辦法使用提供的方法了,只能業務自己來保證線程安全了,比如下面這樣其它業務操作這樣雖然不太友好,但是最起碼能保證業務邏輯是正確的。 刪除元素 刪除元素跟添加元素一樣,都是先找到元素所在的桶,然后采用分段鎖的思想鎖住整個桶,再進行操作。 public V remove(Objec...
摘要:原因是它支持多線程進行擴容操作,而并沒有加鎖。多線程的情況下如果一個或多個線程正在對進行擴容操作,當前線程也要進入擴容的操作中。 KillCode系列 -- Java篇 原文發布在我的個人博客中killCode 因為JDK1.8 與 1.7 里對ConcurrentHashMap 有很多不同的更改以提高性能。所以特別找出類似的方面,進行分析。 1. 內部參數 //初始容積為 16 p...
摘要:一擴容的基本思路中,最復雜的部分就是擴容數據遷移,涉及多線程的合作和。單線程注意這兩種情況都是調用了方法,通過第二個入參進行區分表示擴容后的新數組,如果為,表示首次發起擴容。第二種情況下,是通過和移位運算來保證僅有一個線程能發起擴容。 showImg(https://segmentfault.com/img/bVbf0J0?w=1000&h=663); 本文首發于一世流云專欄:http...
摘要:上一篇文章已經就進行了部分說明,介紹了其中涉及的常量和變量的含義,有些部分需要結合方法源碼來理解,今天這篇文章就繼續講解并發前言本文主要介紹中的一些重要方法,結合上篇文章中的講解部分進行更進一步的介紹回顧下上篇文章,我們應該已經知道的整體結 上一篇文章已經就ConcurrentHashMap進行了部分說明,介紹了其中涉及的常量和變量的含義,有些部分需要結合方法源碼來理解,今天這篇文章就...
摘要:最近準備面試,一談到基礎,大部分面試官上來就數據結構素質三連與區別,底層數據結構,為什么能保證線程安全。數組順序存儲,內存連續,查詢快,插入刪除效率稍微低,不過現在略有改善。而在開始,是由和的方式去實現高并發下的線程安全。 最近準備面試,一談到java基礎,大部分面試官上來就java數據結構素質三連:ArrayList與LinkedList區別,HashMap底層數據結構,Concur...
閱讀 1008·2021-10-27 14:15
閱讀 2763·2021-10-25 09:45
閱讀 1923·2021-09-02 09:45
閱讀 3357·2019-08-30 15:55
閱讀 1798·2019-08-29 16:05
閱讀 3189·2019-08-28 18:13
閱讀 3109·2019-08-26 13:58
閱讀 442·2019-08-26 12:01