一嫉戚、String和Stringbuffer和StringBuilder的區(qū)別贴见?
String:字符串常量
StringBuffer:字符串變量;線程安全的
StringBuilder:字符串變量;線程非安全的
三者執(zhí)行速度比較:StringBuilder > StringBuffer > String
1.String類的內(nèi)容一旦聲明后是不可改變的禽作,改變的只是其內(nèi)存的指向,而StringBuffer類的對(duì)象內(nèi)容是可以改變的岸裙。
2.對(duì)于StringBuffer猖败,不能像String那樣直接通過(guò)賦值的方式完成對(duì)象實(shí)例化,必須通過(guò)構(gòu)造方法的方式完成降允。
3.StringBuffer在進(jìn)行字符串處理時(shí)恩闻,不生成新的對(duì)象,在內(nèi)存使用上要優(yōu)于字符串類剧董。所以在實(shí)際使用時(shí)幢尚,如果經(jīng)常需要對(duì)一個(gè)字符串進(jìn)行修改,例如插入翅楼,刪除等操作尉剩,使用StringBuffer要更加適合一些。
4.StringBuilder毅臊,StringBuffer 之間的最大不同在于 StringBuilder 的方法是線程非安全的(不能同步訪問(wèn))理茎。
5.StringBuilder 相較于 StringBuffer 有速度優(yōu)勢(shì),所以多數(shù)情況下建議使用?StringBuilder 類管嬉,然而在應(yīng)用程序要求線程安全的情況下功蜓,則必須使用?StringBuffer 類。
StringBuilder與StringBuffer二者的區(qū)別主要是在運(yùn)行速度和線程安全這兩方面宠蚂。
1式撼、StringBuffer 與 StringBuilder 中的方法和功能完全是等價(jià)的
2、只是StringBuffer 中的方法大都采用了?synchronized?關(guān)鍵字進(jìn)行修飾求厕,因此是線程安全的著隆,而 StringBuilder 沒(méi)有這個(gè)修飾,可以被認(rèn)為是線程不安全的呀癣。
3美浦、在單線程程序下,StringBuilder效率更快项栏,因?yàn)樗恍枰渔i浦辨,不具備多線程安全而StringBuffer則每次都需要判斷鎖,效率相對(duì)更低沼沈。
三者使用的總結(jié):1.如果要操作少量的數(shù)據(jù)用 = String
2.單線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuilder
3.多線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuffer
二流酬、ArrayList,Vector, LinkedList的存儲(chǔ)性能和特性
??ArrayList和Vector都是使用數(shù)組方式存儲(chǔ)數(shù)據(jù),此數(shù)組元素?cái)?shù)大于實(shí)際存儲(chǔ)數(shù)據(jù)以便增加和插入元素列另,它們都允許直接按序號(hào)索引元素芽腾,但是插入元素要涉及數(shù)組元素移動(dòng)等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢页衙,Vector由于使用了synchronized思路方法(線程安全) 摊滔,通常性能上較ArrayList差阴绢,而LinkedList使用雙向鏈表實(shí)現(xiàn)存儲(chǔ),按序號(hào)索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷艰躺,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)前后項(xiàng)即可呻袭,所以插入速度較快
三、HashMap和Hashtable的區(qū)別
HashMap:①線程非安全的?
? ? ? ? ? ? ? ? ? ?②性能方面:由于線程是非安全的腺兴,所以每個(gè)方法不需要阻塞其他線程棒妨,所以性能要優(yōu)于HashTable
? ? ? ? ? ? ? ? ? ?③空值問(wèn)題:允許鍵值為Null
? ? ? ? ? ? ? ? ? ?④實(shí)現(xiàn)方式:繼承AbstractMap類
? ? ? ? ? ? ? ? ? ?⑤擴(kuò)容:源碼中初始值 1 << 4 ,初始值為16,負(fù)載因子默認(rèn)為0.75(詳細(xì)請(qǐng)看該鏈接下《說(shuō)說(shuō)hashMap 使用的是哪種數(shù)據(jù)結(jié)構(gòu)》鏈接內(nèi)容)
? ? ? ? ? ? ? ? ? ?⑥迭代器:HashMap 中的 Iterator 迭代器是 fail-fast 的含长,當(dāng)其他線程改變了HashMap 的結(jié)構(gòu)券腔,如:增加、刪除元素拘泞,將會(huì)拋出 ConcurrentModificationException 異常纷纫,而 Hashtable 則不會(huì)。
HashTable:①線程安全的陪腌,線程安全的原因是所有的元素操作都是用synchronized修飾的辱魁,而HashMap沒(méi)有
? ? ? ? ? ? ? ? ? ? ?②性能方面:由于是線程安全的,所以每個(gè)方法需要阻塞其他線程诗鸭,所以性能要弱于HashMap
? ? ? ? ? ? ? ? ? ? ?③空值問(wèn)題:不允許鍵值為null
? ? ? ? ? ? ? ? ? ? ?④實(shí)現(xiàn)方式:繼承Dictionary類
? ? ? ? ? ? ? ? ? ? ?⑤擴(kuò)容:源碼中初始值為11染簇,負(fù)載因子默認(rèn)為0.75
? ? ? ? ? ? ? ? ? ? ?⑥迭代器:?Hashtable 的 Enumerator 不是 fail-fast 的,Enumeration是個(gè)接口强岸,不是類锻弓,再次,這個(gè)東西就是為了實(shí)現(xiàn)遍歷的蝌箍,現(xiàn)在已經(jīng)被迭代器Iterator取代了青灼,Enumeration和iterator最主要區(qū)別,其實(shí)就是Iterator可以刪除元素妓盲,但是Enumration卻不能杂拨。
最大的區(qū)別是,Hashtable的思路方法是Synchronize的悯衬,而HashMap不是弹沽,在多個(gè)線程訪問(wèn)Hashtable時(shí),不需要自己為它的思路方法實(shí)現(xiàn)同步筋粗,而HashMap?就必須為的提供外同步策橘。
四、?final, finally, finalize的區(qū)別
final:用于聲明屬性亏狰,方法和類役纹,分別表示屬性不可變,方法不可覆蓋暇唾,類不可繼承。
finally:是異常處理語(yǔ)句結(jié)構(gòu)的一部分,表示總是執(zhí)行策州。?
finalize:是Object類的一個(gè)方法瘸味,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收够挂,例如關(guān)閉文件等旁仿。
五、swtich是否能作用在byte上孽糖,是否能作用在long上枯冈,是否能作用在String上?
swtich中只能用byte?short?int?char
六、線程的幾種狀態(tài)
創(chuàng)建:當(dāng)new了一個(gè)線程办悟,并沒(méi)有調(diào)用start之前尘奏,線程處于創(chuàng)建狀態(tài);
就緒:當(dāng)調(diào)用了start之后病蛉,線程處于就緒狀態(tài)炫加,這是,線程調(diào)度程序還沒(méi)有設(shè)置執(zhí)行當(dāng)前線程铺然;
運(yùn)行:線程調(diào)度程序執(zhí)行到線程時(shí)俗孝,當(dāng)前線程從就緒狀態(tài)轉(zhuǎn)成運(yùn)行狀態(tài),開(kāi)始執(zhí)行run方法里邊的代碼魄健;
阻塞:線程在運(yùn)行的時(shí)候赋铝,被暫停執(zhí)行(通常等待某項(xiàng)資源就緒后在執(zhí)行,sleep沽瘦、wait可以導(dǎo)致線程阻塞)柬甥,這是該線程處于阻塞狀態(tài);
死亡:當(dāng)一個(gè)線程執(zhí)行完run方法里邊的代碼或調(diào)用了stop方法后其垄,該線程結(jié)束運(yùn)行
生命周期如下圖:
七苛蒲、多線程有幾種實(shí)現(xiàn)方式?
多線程的幾種實(shí)現(xiàn)方式:①繼承Thread類,重寫(xiě)Run()
? ??????????????????????????????????????②實(shí)現(xiàn)Runnable接口,創(chuàng)建步驟如下:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?定義一個(gè)類實(shí)現(xiàn)Runnable接口绿满,作為線程任務(wù)類
????????????????????????????????????????????????????重寫(xiě)run方法臂外,并實(shí)現(xiàn)方法體,方法體的代碼就是線程所執(zhí)行的代碼
????????????????????????????????????????????????????定義一個(gè)可以運(yùn)行的類喇颁,并在main方法中創(chuàng)建線程任務(wù)類
????????????????????????????????????????????????????創(chuàng)建Thread類漏健,并將線程任務(wù)類做為T(mén)hread類的構(gòu)造方法傳入
????????????????????????????????????????????????????啟動(dòng)線程
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ③使用內(nèi)部類的方式:將Thread和Runnable作為內(nèi)部子類實(shí)現(xiàn)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ④定時(shí)器:定時(shí)器Timer(JDK提供API)是一個(gè)基于線程的工具類,可以定時(shí)的來(lái)執(zhí)行某個(gè)任務(wù)橘霎。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?提供定時(shí)任務(wù)的三方框架:Spring的Schedule和Quartz框架
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?⑤帶返回值的線程實(shí)現(xiàn)方式:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1)實(shí)現(xiàn)Callable接口蔫浆,實(shí)現(xiàn)call(),這個(gè)接口類似于Runnable接口,但比Runnable接口更加強(qiáng)大姐叁,? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 增加了異常和返回值瓦盛。?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2)創(chuàng)建一個(gè)FutureTask洗显,指定Callable對(duì)象,做為線程任務(wù)原环。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 3)創(chuàng)建線程挠唆,指定線程任務(wù)。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 4)啟動(dòng)線程
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ⑥基于線程池的方式:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 概念:一些線程的集合稱為線程池嘱吗,線程池可以很好的提高性能玄组,線程池在系統(tǒng)啟動(dòng)時(shí)創(chuàng)建大量的空閑線程,程序?qū)⑷蝿?wù)提交以后谒麦,線程就會(huì)啟動(dòng)一個(gè)線程執(zhí)行該任務(wù)俄讹,任務(wù)結(jié)束以后,線程并不會(huì)死亡绕德,而是返回線程池患膛,成為空閑狀態(tài),當(dāng)代執(zhí)行下一個(gè)任務(wù)迁匠。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?工作機(jī)制:①在線程池的編程模式下剩瓶,任務(wù)是提交給整個(gè)線程池的,而不是直接提交給某一個(gè)線程城丧,線程池在獲取到任務(wù)后延曙,會(huì)尋找是否有空閑的線程,如果有則將任務(wù)提交給這個(gè)線程
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?②一個(gè)線程只能執(zhí)行一個(gè)任務(wù)亡哄,但可以同時(shí)向一個(gè)線程池提交多個(gè)任務(wù)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?使用線程池的原因:多線程運(yùn)行時(shí)枝缔,系統(tǒng)會(huì)不斷的啟動(dòng)和關(guān)閉新線程,成本高蚊惯,會(huì)過(guò)度消耗資源愿卸,以及過(guò)度的切換線程,會(huì)造成系統(tǒng)資源的崩潰截型,所以趴荸,線程池是最優(yōu)選擇
四種常見(jiàn)的線程池:
①線程池的返回值都是ExecutorService,ExecutorService是Java提供的用于管理線程池的類宦焦。該類作用是:控制線程數(shù)量和重用線程
②四種線程池介紹:
1)Executors.newCacheThreadPool():可緩存線程池发钝,先查看池中有沒(méi)有以前建立的線程,如果有波闹,就直接使用酝豪。如果沒(méi)有,就建一個(gè)新的線程加入池中精堕,緩存型池子通常用于執(zhí)行一些生存期很短的異步型任務(wù)
2)Executors.newFixedThreadPool(int n):創(chuàng)建一個(gè)可重用固定個(gè)數(shù)的線程池孵淘,以共享的無(wú)界隊(duì)列方式來(lái)運(yùn)行這些線程。
3)Executors.newScheduledThreadPool(int n):創(chuàng)建一個(gè)定長(zhǎng)線程池歹篓,支持定時(shí)及周期性任務(wù)執(zhí)行
4)Executors.newSingleThreadExecutor():創(chuàng)建一個(gè)單線程化的線程池瘫证,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù)揉阎,保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級(jí))執(zhí)行。
八痛悯、線程池的參數(shù)總結(jié):
①corePoolSize:核心線程數(shù)
????????* 核心線程會(huì)一直存活余黎,及時(shí)沒(méi)有任務(wù)需要執(zhí)行
?????????* 當(dāng)線程數(shù)小于核心線程數(shù)時(shí)重窟,即使有線程空閑载萌,線程池也會(huì)優(yōu)先創(chuàng)建新線程處理
?????????* 設(shè)置? allowCoreThreadTimeout=true(默認(rèn)false)時(shí),核心線程會(huì)超時(shí)關(guān)閉
②queueCapacity:任務(wù)隊(duì)列容量(阻塞隊(duì)列)
?????????* 當(dāng)核心線程數(shù)達(dá)到最大時(shí)巡扇,新任務(wù)會(huì)放在隊(duì)列中排隊(duì)等待執(zhí)行
③maxPoolSize:最大線程數(shù)
?????????* 當(dāng)線程數(shù)>=corePoolSize扭仁,且任務(wù)隊(duì)列已滿時(shí)。線程池會(huì)創(chuàng)建新線程來(lái)處理任務(wù)
? ? ? ? ?* 當(dāng)線程數(shù)=maxPoolSize厅翔,且任務(wù)隊(duì)列已滿時(shí)乖坠,線程池會(huì)拒絕處理任務(wù)而拋出異常
④keepAliveTime:線程空閑時(shí)間
? ? ? ? ???* 當(dāng)線程空閑時(shí)間達(dá)到? keepAliveTime時(shí),線程會(huì)退出刀闷,直到線程數(shù)量=corePoolSize
? ? ? ? ? ?* 如果 allowCoreThreadTimeout=true熊泵,則會(huì)直到線程數(shù)量=0
⑤allowCoreThreadTimeout:允許核心線程超時(shí)
⑥r(nóng)ejectedExecutionHandler:任務(wù)拒絕處理器
? ??????????* 兩種情況會(huì)拒絕處理任務(wù):
? ? ? ? ? ? - 當(dāng)線程數(shù)已經(jīng)達(dá)到 maxPoolSize ,切隊(duì)列已滿甸昏,會(huì)拒絕新任務(wù)
? ? ? ? ? ? - 當(dāng)線程池被調(diào)用 shutdown()后顽分,會(huì)等待線程池里的任務(wù)執(zhí)行完畢,再shutdown施蜜。如果在調(diào)用 shutdown()和線程池真正 shutdown之間提交任務(wù)卒蘸,會(huì)拒絕新任務(wù)
? ? ? ? * 線程池會(huì)調(diào)用 rejectedExecutionHandler來(lái)處理這個(gè)任務(wù)。如果沒(méi)有設(shè)置默認(rèn)是AbortPolicy翻默,會(huì)拋出異常
? ? ? ? * ThreadPoolExecutor類有幾個(gè)內(nèi)部實(shí)現(xiàn)類來(lái)處理這類情況:
? ? ? ? ? ? - AbortPolicy 丟棄任務(wù)缸沃,拋運(yùn)行時(shí)異常
? ? ? ? ? ? - CallerRunsPolicy 執(zhí)行任務(wù)
? ? ? ? ? ? - DiscardPolicy 忽視,什么都不會(huì)發(fā)生
? ? ? ? ? ? - DiscardOldestPolicy 從隊(duì)列中踢出最先進(jìn)入隊(duì)列(最后一個(gè)執(zhí)行)的任務(wù)
? ? ? ? * 實(shí)現(xiàn) RejectedExecutionHandler 接口修械,可自定義處理器
基于JDK1.8的ConcurrentHashMap的源碼分析:
ConcurrentHashMap是線程安全的趾牧,利用的是 CAS算法和Synchronized 來(lái)保證并發(fā)更新的安全
數(shù)據(jù)機(jī)構(gòu)是:數(shù)組+鏈表+紅黑樹(shù)
重要的成員變量:
? ? table:默認(rèn)為null,初始化發(fā)生在第一次插入操作肯污,默認(rèn)大小為16的數(shù)組翘单,用來(lái)存儲(chǔ)Node節(jié)點(diǎn)數(shù)據(jù),擴(kuò)容時(shí)大小總是2的冪次方仇箱。
? ??nextTable:默認(rèn)為null县恕,擴(kuò)容時(shí)新生成的數(shù)組,其大小為原數(shù)組的兩倍剂桥。
? ??sizeCtl :默認(rèn)為0忠烛,用來(lái)控制table的初始化和擴(kuò)容操作,具體應(yīng)用在后續(xù)會(huì)體現(xiàn)出來(lái)权逗。
? ? ? ? ? ?① -1 代表table正在初始化
? ? ? ? ? ? ②-N 表示有N-1個(gè)線程正在進(jìn)行擴(kuò)容操作
? ? ? ? ? ? ③其余情況:
????????????????????1美尸、如果table未初始化冤议,表示table需要初始化的大小。
? ? ? ? ? ? ? ? ? ? ?2师坎、如果table初始化完成恕酸,表示table的容量,默認(rèn)是table大小的0.75倍胯陋,居然用這個(gè)公式算0.75(n - (n >>> 2))蕊温。
```
public classConcurrentHashMapextendsAbstractMapimplementsConcurrentMap, Serializable {private static final longserialVersionUID = 7249069246763182397L;// 表的最大容量private static final intMAXIMUM_CAPACITY = 1 << 30;// 默認(rèn)表的大小private static final intDEFAULT_CAPACITY = 16;// 最大數(shù)組大小static final intMAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;// 默認(rèn)并發(fā)數(shù)private static final intDEFAULT_CONCURRENCY_LEVEL = 16;// 裝載因子private static final floatLOAD_FACTOR = 0.75f;// 轉(zhuǎn)化為紅黑樹(shù)的閾值static final intTREEIFY_THRESHOLD = 8;// 由紅黑樹(shù)轉(zhuǎn)化為鏈表的閾值static final intUNTREEIFY_THRESHOLD = 6;// 轉(zhuǎn)化為紅黑樹(shù)的表的最小容量static final intMIN_TREEIFY_CAPACITY = 64;// 每次進(jìn)行轉(zhuǎn)移的最小值private static final intMIN_TRANSFER_STRIDE = 16;// 生成sizeCtl所使用的bit位數(shù)private static intRESIZE_STAMP_BITS = 16;// 進(jìn)行擴(kuò)容所允許的最大線程數(shù)private static final intMAX_RESIZERS = (1 << (32 - RESIZE_STAMP_BITS)) - 1;// 記錄sizeCtl中的大小所需要進(jìn)行的偏移位數(shù)private static final intRESIZE_STAMP_SHIFT = 32 - RESIZE_STAMP_BITS;// 一系列的標(biāo)識(shí)static final intMOVED = -1;// hash for forwarding nodesstatic final intTREEBIN = -2;// hash for roots of treesstatic final intRESERVED = -3;// hash for transient reservationsstatic final intHASH_BITS = 0x7fffffff;// usable bits of normal node hash//
? ? /** Number of CPUS, to place bounds on some sizings */
? ? // 獲取可用的CPU個(gè)數(shù)static final intNCPU = Runtime.getRuntime().availableProcessors();//
? ? /** For serialization compatibility. */
? ? // 進(jìn)行序列化的屬性private static finalObjectStreamField[] serialPersistentFields = {newObjectStreamField("segments", Segment[].class),newObjectStreamField("segmentMask", Integer.TYPE),newObjectStreamField("segmentShift", Integer.TYPE)? ? };// 表transient volatileNode[] table; // 下一個(gè)表private transient volatileNode[] nextTable; //
? ? /**
? ? * Base counter value, used mainly when there is no contention,
? ? * but also as a fallback during table initialization
? ? * races. Updated via CAS.
? ? */
? ? // 基本計(jì)數(shù)private transient volatile longbaseCount; //
? ? /**
? ? * Table initialization and resizing control.? When negative, the
? ? * table is being initialized or resized: -1 for initialization,
? ? * else -(1 + the number of active resizing threads).? Otherwise,
? ? * when table is null, holds the initial table size to use upon
? ? * creation, or 0 for default. After initialization, holds the
? ? * next element count value upon which to resize the table.
? ? */
? ? // 對(duì)表初始化和擴(kuò)容控制private transient volatile intsizeCtl;/**
? ? * The next table index (plus one) to split while resizing.
? ? */
? ? // 擴(kuò)容下另一個(gè)表的索引private transient volatile inttransferIndex;/**
? ? * Spinlock (locked via CAS) used when resizing and/or creating CounterCells.
? ? */
? ? // 旋轉(zhuǎn)鎖private transient volatile intcellsBusy;/**
? ? * Table of counter cells. When non-null, size is a power of 2.
? ? */
? ? // counterCell表private transientvolatileCounterCell[] counterCells;// views
? ? // 視圖private transientKeySetView keySet;private transientValuesView values;private transientEntrySetView entrySet; // Unsafe mechanicsprivate static finalsun.misc.Unsafe U;private static final longSIZECTL;private static final longTRANSFERINDEX;private static final longBASECOUNT;private static final longCELLSBUSY;private static final longCELLVALUE;private static final longABASE;private static final intASHIFT; static{try{? ? ? ? ? ? U = sun.misc.Unsafe.getUnsafe();? ? ? ? ? ? Class k = ConcurrentHashMap.class;? ? ? ? ? ? SIZECTL = U.objectFieldOffset? ? ? ? ? ? ? ? (k.getDeclaredField("sizeCtl"));? ? ? ? ? ? TRANSFERINDEX = U.objectFieldOffset? ? ? ? ? ? ? ? (k.getDeclaredField("transferIndex"));? ? ? ? ? ? BASECOUNT = U.objectFieldOffset? ? ? ? ? ? ? ? (k.getDeclaredField("baseCount"));? ? ? ? ? ? CELLSBUSY = U.objectFieldOffset? ? ? ? ? ? ? ? (k.getDeclaredField("cellsBusy"));? ? ? ? ? ? Class ck = CounterCell.class;? ? ? ? ? ? CELLVALUE = U.objectFieldOffset? ? ? ? ? ? ? ? (ck.getDeclaredField("value"));? ? ? ? ? ? Class ak = Node[].class;? ? ? ? ? ? ABASE = U.arrayBaseOffset(ak);intscale = U.arrayIndexScale(ak);if((scale & (scale - 1)) != 0)throw newError("data type scale not a power of two");? ? ? ? ? ? ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);? ? ? ? }catch(Exception e) {throw newError(e);? ? ? ? }? ? }}
```