Youtu-VL-4B-Instruct完整指南:WebUI界面功能详解+API错误排查速查表
1ã€�HashMap底层æº�ç � 难度系数â�â�â�HashMap的底层结æ�„在jdk
7ä¸ç”±æ•°ç»„链表å®�ç�°åœ¨jdk
8ä¸ç”±æ•°ç»„é“¾è¡¨çº¢é»‘æ ‘å®�ç�°ä»¥æ•°ç»„链表的结æ�„为例。JDK
8之�Put方法JDK
8之å��Put方法HashMap基äº�哈希表的Mapæ�¥å�£å®�ç�°æ˜¯ä»¥key-valueå˜å‚¨å½¢å¼�å˜åœ¨å�³ä¸»è¦�用æ�¥å˜æ”¾é”®å€¼å¯¹ã€‚HashMap çš„å®�ç�°ä¸�是å�Œæ¥çš„è¿™æ„�味ç�€å®ƒä¸�是线程安全的。它的keyã€�value都å�¯ä»¥ä¸ºnull。æ¤å¤–HashMapä¸çš„æ˜ å°„ä¸�是有åº�的。JDK
8 之å‰� HashMap ç”± 数组链表 组æˆ�的数组是 HashMap 的主体链表则是主è¦�为了解决哈希冲çª�(两个对象调用的hashCode方法计算的哈希ç �值一致导致计算的数组索引值相å�Œ)而å˜åœ¨çš„“拉链法â€�解决冲çª�.JDK
8 以å��在解决哈希冲çª�时有了较大的å�˜åŒ–当链表长度大äº�é˜ˆå€¼æˆ–è€…çº¢é»‘æ ‘çš„è¾¹ç•Œå€¼é»˜è®¤ä¸º 8并且当å‰�数组的长度大äº�64æ—¶æ¤æ—¶æ¤ç´¢å¼•ä½�置上的所有数æ�®æ”¹ä¸ºä½¿ç”¨çº¢é»‘æ ‘å˜å‚¨ã€‚补充将链表转æ�¢æˆ�çº¢é»‘æ ‘å‰�会判æ–å�³ä½¿é˜ˆå€¼å¤§äº�8但是数组长度å°�äº�64æ¤æ—¶å¹¶ä¸�会将链表å�˜ä¸ºçº¢é»‘æ ‘ã€‚è€Œæ˜¯é€‰æ‹©è¿›è¡Œæ•°ç»„æ‰©å®¹ã€‚è¿™æ ·å�šçš„ç›®çš„æ˜¯å› ä¸ºæ•°ç»„æ¯”è¾ƒå°�å°½é‡�é�¿å¼€çº¢é»‘æ ‘ç»“æ�„è¿™ç§�情况下å�˜ä¸ºçº¢é»‘æ ‘ç»“æ�„å��而会é™�ä½�效ç�‡å› ä¸ºçº¢é»‘æ ‘éœ€è¦�进行左旋å�³æ—‹å�˜è‰²è¿™äº›æ“�作æ�¥ä¿�æŒ�平衡 。å�Œæ—¶æ•°ç»„长度å°�äº�64æ—¶æ�œç´¢æ—¶é—´ç›¸å¯¹è¦�快些。所以综上所述为了æ��高性能和å‡�å°‘æ�œç´¢æ—¶é—´åº•层在阈值大äº�8并且数组长度大äº�64时链表æ‰�转æ�¢ä¸ºçº¢é»‘æ ‘ã€‚å…·ä½“å�¯ä»¥å�‚考 treeifyBin方法。当然虽然å¢�äº†çº¢é»‘æ ‘ä½œä¸ºåº•å±‚æ•°æ�®ç»“æ�„结æ�„å�˜å¾—å¤�æ�‚了但是阈值大äº�8并且数组长度大äº�64时链表转æ�¢ä¸ºçº¢é»‘æ ‘æ—¶æ•ˆç�‡ä¹Ÿå�˜çš„æ›´é«˜æ•ˆã€‚篇幅é™�制下é�¢å°±å�ªèƒ½ç»™å¤§å®¶å±•示å°�册部分内容了。整ç�†äº†ä¸€ä»½æ ¸å¿ƒé�¢è¯•笔记包括了Javaé�¢è¯•ã€�Springã€�JVMã€�MyBatisã€�Redisã€�MySQLã€�å¹¶å�‘编程ã€�å¾®æœ�务ã€�Linuxã€�Springbootã€�SpringCloudã€�MQã€�Kafc需è¦�全套é�¢è¯•笔记å�Šç”案ã€�点击æ¤å¤„å�³å�¯/å…�è´¹è�·å�–】​https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1ho2ã€�JVM内å˜åˆ†å“ªå‡ 个区æ¯�个区的作用是什么 难度系数â�â�java虚拟机主è¦�åˆ†ä¸ºä»¥ä¸‹å‡ ä¸ªåŒºæ–¹æ³•åŒºæœ‰æ—¶å€™ä¹Ÿæˆ�为永久代在该区内很少å�‘生å�ƒåœ¾å›�收但是并ä¸�代表ä¸�å�‘生GC在这里进行的GC主è¦�是对方法区里的常é‡�æ± å’Œå¯¹ç±»å�‹çš„å�¸è½½æ–¹æ³•区主è¦�用æ�¥å˜å‚¨å·²è¢«è™šæ‹ŸæœºåŠ è½½çš„ç±»çš„ä¿¡æ�¯ã€�常é‡�ã€�é�™æ€�å�˜é‡�å’Œå�³æ—¶ç¼–译器编译å��的代ç �ç‰æ•°æ�®ã€‚该区域是被线程共享的。方法区里有一个è¿�行时常é‡�æ± ç”¨äº�å˜æ”¾é�™æ€�编译产生的å—é�¢é‡�和符å�·å¼•用。该常é‡�æ± å…·æœ‰åŠ¨æ€�性也就是说常é‡�å¹¶ä¸�一定是编译时确定è¿�行时生æˆ�的常é‡�也会å˜åœ¨è¿™ä¸ªå¸¸é‡�æ± ä¸ã€‚è™šæ‹Ÿæœºæ ˆè™šæ‹Ÿæœºæ ˆä¹Ÿå°±æ˜¯æˆ‘ä»¬å¹³å¸¸æ‰€ç§°çš„æ ˆå†…å˜,它为java方法æœ�务æ¯�ä¸ªæ–¹æ³•åœ¨æ‰§è¡Œçš„æ—¶å€™éƒ½ä¼šåˆ›å»ºä¸€ä¸ªæ ˆå¸§ç”¨äº�å˜å‚¨å±€éƒ¨å�˜é‡�表ã€�æ“�ä½œæ•°æ ˆã€�动æ€�链æ�¥å’Œæ–¹æ³•出å�£ç‰ä¿¡æ�¯ã€‚è™šæ‹Ÿæœºæ ˆæ˜¯çº¿ç¨‹ç§�有的它的生命周期ä¸�线程相å�Œã€‚局部å�˜é‡�表里å˜å‚¨çš„æ˜¯åŸºæœ¬æ•°æ�®ç±»å�‹ã€�returnAddressç±»å�‹æŒ‡å�‘一æ�¡å—节ç �指令的地å�€å’Œå¯¹è±¡å¼•用这个对象引用有å�¯èƒ½æ˜¯æŒ‡å�‘对象起始地å�€çš„一个指针也有å�¯èƒ½æ˜¯ä»£è¡¨å¯¹è±¡çš„å�¥æŸ„或者ä¸�对象相关è�”çš„ä½�置。局部å�˜é‡�所需的内å˜ç©ºé—´åœ¨ç¼–译器间确定æ“�ä½œæ•°æ ˆçš„ä½œç”¨ä¸»è¦�用æ�¥å˜å‚¨è¿�算结æ�œä»¥å�Šè¿�ç®—çš„æ“�作数它ä¸�å�Œäº�局部å�˜é‡�表通过索引æ�¥è®¿é—®è€Œæ˜¯å�‹æ ˆå’Œå‡ºæ ˆçš„æ–¹å¼�æ¯�ä¸ªæ ˆå¸§éƒ½åŒ…å�«ä¸€ä¸ªæŒ‡å�‘è¿�行时常é‡�æ± ä¸è¯¥æ ˆå¸§æ‰€å±�方法的引用æŒ�有这个引用是为了支æŒ�方法调用过程ä¸çš„动æ€�è¿�æ�¥.动æ€�链æ�¥å°±æ˜¯å°†å¸¸é‡�æ± ä¸çš„符å�·å¼•用在è¿�行期转化为直æ�¥å¼•ç”¨ã€‚æœ¬åœ°æ–¹æ³•æ ˆæœ¬åœ°æ–¹æ³•æ ˆå’Œè™šæ‹Ÿæœºæ ˆç±»ä¼¼å�ªä¸�è¿‡æœ¬åœ°æ–¹æ³•æ ˆä¸ºNative方法æœ�åŠ¡ã€‚å †javaå †æ˜¯æ‰€æœ‰çº¿ç¨‹æ‰€å…±äº«çš„ä¸€å�—内å˜åœ¨è™šæ‹Ÿæœºå�¯åŠ¨æ—¶åˆ›å»ºå‡ ä¹�所有的对象å®�ä¾‹éƒ½åœ¨è¿™é‡Œåˆ›å»ºå› æ¤è¯¥åŒºåŸŸç»�常å�‘生å�ƒåœ¾å›�æ”¶æ“�作。程åº�计数器内å˜ç©ºé—´å°�å—节ç �解释器工作时通过改å�˜è¿™ä¸ªè®¡æ•°å€¼å�¯ä»¥é€‰å�–下一æ�¡éœ€è¦�执行的å—节ç �指令分支ã€�循ç�¯ã€�跳转ã€�异常处ç�†å’Œçº¿ç¨‹æ�¢å¤�ç‰åŠŸèƒ½éƒ½éœ€è¦�ä¾�赖这个计数器完æˆ�。该内å˜åŒºåŸŸæ˜¯å”¯ä¸€ä¸€ä¸ªjava虚拟机规范没有规定任何OOM情况的区域。3ã€�Javaä¸å�ƒåœ¾æ”¶é›†çš„æ–¹æ³•有哪些 难度系数â�采用分区分代å›�æ”¶æ€�想å¤�制算法年轻代ä¸ä½¿ç”¨çš„æ˜¯Minor GCè¿™ç§�GC算法采用的是å¤�制算法(Copying)a) 效ç�‡é«˜ç¼ºç‚¹éœ€è¦�内å˜å®¹é‡�大比较耗内å˜b) 使用在å� 空间比较å°�ã€�åˆ·æ–°æ¬¡æ•°å¤šçš„æ–°ç”ŸåŒºæ ‡è®°-清除è€�å¹´ä»£ä¸€èˆ¬æ˜¯ç”±æ ‡è®°æ¸…é™¤æˆ–è€…æ˜¯æ ‡è®°æ¸…é™¤ä¸�æ ‡è®°æ•´ç�†çš„æ··å�ˆå®�ç�°a) 效ç�‡æ¯”较ä½�会差生ç¢�ç‰‡ã€‚æ ‡è®°-æ•´ç�†è€�å¹´ä»£ä¸€èˆ¬æ˜¯ç”±æ ‡è®°æ¸…é™¤æˆ–è€…æ˜¯æ ‡è®°æ¸…é™¤ä¸�æ ‡è®°æ•´ç�†çš„æ··å�ˆå®�ç�°a) 效ç�‡ä½�速度慢需è¦�移动对象但ä¸�会产生ç¢�片。4ã€�如何判æ–一个对象是å�¦å˜æ´»(或者GC对象的判定方法) 难度系数â�引用计数法所谓引用计数法就是给æ¯�一个对象设置一个引用计数器æ¯�å½“æœ‰ä¸€ä¸ªåœ°æ–¹å¼•ç”¨è¿™ä¸ªå¯¹è±¡æ—¶å°±å°†è®¡æ•°å™¨åŠ ä¸€å¼•ç”¨å¤±æ•ˆæ—¶è®¡æ•°å™¨å°±å‡�一。当一个对象的引用计数器为零时说æ˜�æ¤å¯¹è±¡æ²¡æœ‰è¢«å¼•用也就是“æ»å¯¹è±¡â€�,将会被å�ƒåœ¾å›�æ”¶.å¼•ç”¨è®¡æ•°æ³•æœ‰ä¸€ä¸ªç¼ºé™·å°±æ˜¯æ— æ³•è§£å†³å¾ªç�¯å¼•用问题也就是说当对象A引用对象B对象Bå�ˆå¼•用者对象Aé‚£ä¹ˆæ¤æ—¶A,B对象的引用计数器都ä¸�ä¸ºé›¶ä¹Ÿå°±é€ æˆ�æ— æ³•å®Œæˆ�å�ƒåœ¾å›�收所以主æµ�的虚拟机都没有采用这ç§�算法。å�¯è¾¾æ€§ç®—法(引用链法)该算法的基本æ€�路就是通过一些被称为引用链GC Roots的对象作为起点ä»�这些节点开始å�‘下æ�œç´¢æ�œç´¢èµ°è¿‡çš„路径被称为Reference Chain)当一个对象到GC Roots没有任何引用链相è¿�æ—¶å�³ä»�GC Roots节点到该节点ä¸�å�¯è¾¾åˆ™è¯�æ˜�该对象是ä¸�å�¯ç”¨çš„。在javaä¸å�¯ä»¥ä½œä¸ºGC Rootsçš„å¯¹è±¡æœ‰ä»¥ä¸‹å‡ ç§�è™šæ‹Ÿæœºæ ˆä¸å¼•用的对象ã€�方法区类é�™æ€�å±�性引用的对象ã€�方法区常é‡�æ± å¼•ç”¨çš„å¯¹è±¡ã€�æœ¬åœ°æ–¹æ³•æ ˆJNI引用的对象。5ã€�什么情况下会产生StackOverflowErroræ ˆæº¢å‡ºå’ŒOutOfMemoryErrorå †æº¢å‡ºæ€�么æ�’查 难度系数â�â�引å�‘ StackOverFlowError 的常è§�å�Ÿå› æœ‰ä»¥ä¸‹å‡ ç§�æ— é™�递归循ç�¯è°ƒç”¨æœ€å¸¸è§�执行了大é‡�æ–¹æ³•å¯¼è‡´çº¿ç¨‹æ ˆç©ºé—´è€—å°½æ–¹æ³•å†…å£°æ˜�了海é‡�的局部å�˜é‡�native 代ç �æœ‰æ ˆä¸Šåˆ†é…�的逻辑并且è¦�求的内å˜è¿˜ä¸�å°�比如 java.net.SocketInputStream.read0 ä¼šåœ¨æ ˆä¸Šè¦�求分é…�一个 64KB 的缓å˜64ä½� Linux。引å�‘ OutOfMemoryError的常è§�å�Ÿå› æœ‰ä»¥ä¸‹å‡ ç§�内å˜ä¸åŠ è½½çš„æ•°æ�®é‡�过äº�åº�大如一次ä»�æ•°æ�®åº“å�–出过多数æ�®é›†å�ˆç±»ä¸æœ‰å¯¹å¯¹è±¡çš„引用使用完å��未清空使得JVMä¸�能å›�收代ç �ä¸å˜åœ¨æ»å¾ªç�¯æˆ–循ç�¯äº§ç”Ÿè¿‡å¤šé‡�å¤�的对象å®�体å�¯åЍå�‚数内å˜å€¼è®¾å®šçš„过å°�æ�’查å�¯ä»¥é€šè¿‡jvisualvm进行内å˜å¿«ç…§åˆ†æ��æ ˆæº¢å‡ºã€�å †æº¢å‡ºæ¡ˆä¾‹æ¼”ç¤ºpublic class StackOverFlowTest {private static int count 1;public static void main(String[] args) {//æ¨¡æ‹Ÿæ ˆæº¢å‡º//getDieCircle();//æ¨¡æ‹Ÿå †æº¢å‡ºgetOutOfMem();}public static void getDieCircle(){System.out.println(count);getDieCircle();}public static void getOutOfMem(){while (true) {Object o new Object();System.out.println(o);}}}Java6ã€�ä»€ä¹ˆæ˜¯çº¿ç¨‹æ± çº¿ç¨‹æ± æœ‰å“ªäº›åˆ›å»º 难度系数â�çº¿ç¨‹æ± å°±æ˜¯äº‹å…ˆå°†å¤šä¸ªçº¿ç¨‹å¯¹è±¡æ”¾åˆ°ä¸€ä¸ªå®¹å™¨ä¸å½“使用的时候就ä¸�用 new 线程而是直æ�¥å�»æ± 䏿‹¿çº¿ç¨‹å�³å�¯èŠ‚çœ�了开辟å�线程的时间æ��高的代ç �执行效ç�‡åœ¨ JDK çš„ java.util.concurrent.Executors 䏿��供了生æˆ�多ç§�çº¿ç¨‹æ± çš„é�™æ€�方法。ExecutorService newCachedThreadPool Executors.newCachedThreadPool();ExecutorService newFixedThreadPool Executors.newFixedThreadPool(
;ScheduledExecutorService newScheduledThreadPool Executors.newScheduledThreadPool(
;ExecutorService newSingleThreadExecutor Executors.newSingleThreadExecutor();ç„¶å��调用他们的 execute 方法å�³å�¯ã€‚è¿™4ç§�çº¿ç¨‹æ± åº•å±‚ 全部是ThreadPoolExecutor对象的å®�ç�°é˜¿é‡Œè§„范手册ä¸è§„å®šçº¿ç¨‹æ± é‡‡ç”¨ThreadPoolExecutor自定义的å®�é™…å¼€å�‘也是。newCachedThreadPool创建一个å�¯ç¼“å˜çº¿ç¨‹æ± 如æ�œçº¿ç¨‹æ± 长度超过处ç�†éœ€è¦�å�¯ç�µæ´»å›�æ”¶ç©ºé—²çº¿ç¨‹è‹¥æ— å�¯å›�收则新建线程。这ç§�ç±»å�‹çš„çº¿ç¨‹æ± ç‰¹ç‚¹æ˜¯å·¥ä½œçº¿ç¨‹çš„åˆ›å»ºæ•°é‡�å‡ ä¹�没有é™�制(å…¶å®�也有é™�制的,数目为Interger. MAX_VALUE), è¿™æ ·å�¯ç�µæ´»çš„å¾€çº¿ç¨‹æ± ä¸æ·»åŠ çº¿ç¨‹ã€‚å¦‚æ�œé•¿æ—¶é—´æ²¡æœ‰å¾€çº¿ç¨‹æ± 䏿��交任务å�³å¦‚æ�œå·¥ä½œçº¿ç¨‹ç©ºé—²äº†æŒ‡å®šçš„æ—¶é—´(默认为1分钟)则该工作线程将自动终æ¢ã€‚终æ¢å��如æ�œä½ å�ˆæ��äº¤äº†æ–°çš„ä»»åŠ¡åˆ™çº¿ç¨‹æ± é‡�新创建一个工作线程。在使用CachedThreadPool时一定è¦�注æ„�æ�§åˆ¶ä»»åŠ¡çš„æ•°é‡�å�¦åˆ™ç”±äº�大é‡�线程å�Œæ—¶è¿�è¡Œå¾ˆæœ‰ä¼šé€ æˆ�系统瘫痪。newFixedThreadPool创建一个指定工作线程数é‡�çš„çº¿ç¨‹æ± ã€‚æ¯�当æ��交一个任务就创建一个工作线程如æ�œå·¥ä½œçº¿ç¨‹æ•°é‡�è¾¾åˆ°çº¿ç¨‹æ± åˆ�始的最大数则将æ��交的任务å˜å…¥åˆ°æ± 队列ä¸ã€‚FixedThreadPool是一个典å�‹ä¸”ä¼˜ç§€çš„çº¿ç¨‹æ± å®ƒå…·æœ‰çº¿ç¨‹æ± æ��高程åº�效ç�‡å’ŒèŠ‚çœ�åˆ›å»ºçº¿ç¨‹æ—¶æ‰€è€—çš„å¼€é”€çš„ä¼˜ç‚¹ã€‚ä½†æ˜¯åœ¨çº¿ç¨‹æ± ç©ºé—²æ—¶å�³çº¿ç¨‹æ± 䏿²¡æœ‰å�¯è¿�行任务时它ä¸�会释放工作线程还会å� 用一定的系统资æº�。newSingleThreadExecutor创建一个å�•线程化的Executorå�³å�ªåˆ›å»ºå”¯ä¸€çš„工作者线程æ�¥æ‰§è¡Œä»»åŠ¡å®ƒå�ªä¼šç”¨å”¯ä¸€çš„工作线程æ�¥æ‰§è¡Œä»»åŠ¡ä¿�è¯�所有任务按照指定顺åº�(FIFO, LIFO, 优先级)执行。如æ�œè¿™ä¸ªçº¿ç¨‹å¼‚常结æ�Ÿä¼šæœ‰å�¦ä¸€ä¸ªå�–代它ä¿�è¯�顺åº�执行。å�•工作线程最大的特点是å�¯ä¿�è¯�顺åº�地执行å�„个任务并且在任æ„�给定的时间ä¸�会有多个线程是活动的。newScheduleThreadPoolåˆ›å»ºä¸€ä¸ªå®šé•¿çš„çº¿ç¨‹æ± è€Œä¸”æ”¯æŒ�定时的以å�Šå‘¨æœŸæ€§çš„任务执行。例如延迟3秒执行。7ã€�为什么è¦�ä½¿ç”¨çº¿ç¨‹æ± éš¾åº¦ç³»æ•°â�çº¿ç¨‹æ± å�šçš„工作主è¦�是æ�§åˆ¶è¿�行的线程数é‡�处ç�†è¿‡ç¨‹ä¸å°†ä»»åŠ¡æ”¾å…¥é˜Ÿåˆ—ç„¶å��在线程创建å��å�¯åŠ¨è¿™äº›ä»»åŠ¡å¦‚æ�œçº¿ç¨‹æ•°é‡�超过了最 大数é‡�超出数é‡�的线程æ�’队ç‰å€™ç‰å…¶å®ƒçº¿ç¨‹æ‰§è¡Œå®Œæ¯•å†�ä»�队列ä¸å�–出任务æ�¥æ‰§è¡Œã€‚主è¦�特点:线程å¤�用;æ�§åˆ¶æœ€å¤§å¹¶å�‘æ•°:管ç�†çº¿ç¨‹ã€‚第一:é™�ä½�资æº�消耗。通过é‡�å¤�利用己创建的线程é™�ä½�线程创建和销æ¯�é€ æˆ�的消耗。第二:æ��高å“�应速度。当任务到达时任务å�¯ä»¥ä¸�需è¦�çš„ç‰åˆ°çº¿ç¨‹åˆ›å»ºå°±èƒ½ç«‹å�³æ‰§è¡Œã€‚第三:æ��高线程的å�¯ç®¡ç�†æ€§ã€‚线程是稀缺资æº�如æ�œæ— é™�制的创建ä¸�仅会消耗系统资æº�还会é™�ä½�ç³»ç»Ÿçš„ç¨³å®šæ€§ä½¿ç”¨çº¿ç¨‹æ± å�¯ä»¥è¿› 行统一的分é…�调优和监æ�§8ã€�çº¿ç¨‹æ± åº•å±‚å·¥ä½œå�Ÿç�† 难度系数â�第一æ¥çº¿ç¨‹æ± 刚创建的时候里é�¢æ²¡æœ‰ä»»ä½•线程ç‰åˆ°æœ‰ä»»åŠ¡è¿‡æ�¥çš„æ—¶å€™æ‰�会创建线程。当然也å�¯ä»¥è°ƒç”¨ prestartAllCoreThreads() 或者 prestartCoreThread() 方法预创建corePoolSize个线程第二æ¥è°ƒç”¨execute()æ��交一个任务时如æ�œå½“å‰�的工作线程数corePoolSizeç›´æ�¥åˆ›å»ºæ–°çš„线程执行这个任务第三æ¥å¦‚æ�œå½“时工作线程数é‡�corePoolSize会将任务放入任务队列ä¸ç¼“å˜ç¬¬å››æ¥å¦‚æ�œé˜Ÿåˆ—å·²æ»¡å¹¶ä¸”çº¿ç¨‹æ± ä¸å·¥ä½œçº¿ç¨‹çš„æ•°é‡�maximumPoolSize还是会创建线程执行这个任务第五æ¥å¦‚æ�œé˜Ÿåˆ—å·²æ»¡å¹¶ä¸”çº¿ç¨‹æ± ä¸çš„线程已达到maximumPoolSize这个时候会执行拒ç»�ç–ç•¥JAVAçº¿ç¨‹æ± é»˜è®¤çš„ç–略是AbortPolicyå�³æŠ›å‡ºRejectedExecutionException异常9ã€�ThreadPoolExecutor对象有哪些å�‚æ•° æ€�ä¹ˆè®¾å®šæ ¸å¿ƒçº¿ç¨‹æ•°å’Œæœ€å¤§çº¿ç¨‹æ•° æ‹’ç»�ç–略有哪些 难度系数â�å�‚æ•°ä¸�作用共7个å�‚æ•°corePoolSizeæ ¸å¿ƒçº¿ç¨‹æ•°åœ¨ThreadPoolExecutor䏿œ‰ä¸€ä¸ªä¸�它相关的é…�ç½®allowCoreThreadTimeOut默认为false当allowCoreThreadTimeOut为falseæ—¶æ ¸å¿ƒçº¿ç¨‹ä¼šä¸€ç›´å˜æ´»å“ªæ€•是一直空闲ç�€ã€‚而当allowCoreThreadTimeOut为trueæ—¶æ ¸å¿ƒçº¿ç¨‹ç©ºé—²æ—¶é—´è¶…è¿‡keepAliveTime时会被å›�收。maximumPoolSizeæœ€å¤§çº¿ç¨‹æ•°çº¿ç¨‹æ± èƒ½å®¹çº³çš„æœ€å¤§çº¿ç¨‹æ•°å½“çº¿ç¨‹æ± ä¸çš„çº¿ç¨‹è¾¾åˆ°æœ€å¤§æ—¶æ¤æ—¶æ·»åŠ ä»»åŠ¡å°†ä¼šé‡‡ç”¨æ‹’ç»�ç–略默认的拒ç»�ç–略是抛出一个è¿�行时错误RejectedExecutionException。值得一æ��的是当åˆ�始化时用的工作队列为LinkedBlockingDequeæ—¶è¿™ä¸ªå€¼å°†æ— æ•ˆã€‚keepAliveTimeå˜æ´»æ—¶é—´å½“é��æ ¸å¿ƒç©ºé—²è¶…è¿‡è¿™ä¸ªæ—¶é—´å°†è¢«å›�æ”¶å�Œæ—¶ç©ºé—²æ ¸å¿ƒçº¿ç¨‹æ˜¯å�¦å›�æ”¶å�—allowCoreThreadTimeOutå½±å“�。unitkeepAliveTimeçš„å�•ä½�。workQueue任务队列常用有三ç§�队列å�³SynchronousQueue,LinkedBlockingDequeæ— ç•Œé˜Ÿåˆ—,ArrayBlockingQueue有界队列。threadFactory线程工å�‚篇幅é™�制下é�¢å°±å�ªèƒ½ç»™å¤§å®¶å±•示å°�册部分内容了。整ç�†äº†ä¸€ä»½æ ¸å¿ƒé�¢è¯•笔记包括了Javaé�¢è¯•ã€�Springã€�JVMã€�MyBatisã€�Redisã€�MySQLã€�å¹¶å�‘编程ã€�å¾®æœ�务ã€�Linuxã€�Springbootã€�SpringCloudã€�MQã€�Kafc需è¦�全套é�¢è¯•笔记å�Šç”案ã€�点击æ¤å¤„å�³å�¯/å…�è´¹è�·å�–】​https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1hoThreadFactory是一个æ�¥å�£ç”¨æ�¥åˆ›å»ºworker。通过线程工å�‚å�¯ä»¥å¯¹çº¿ç¨‹çš„一些å±�性进行定制。默认直æ�¥æ–°å»ºçº¿ç¨‹ã€‚RejectedExecutionHandleræ‹’ç»�ç–略也是一个æ�¥å�£å�ªæœ‰ä¸€ä¸ªæ–¹æ³•å½“çº¿ç¨‹æ± ä¸çš„资æº�å·²ç»�å…¨éƒ¨ä½¿ç”¨æ·»åŠ æ–°çº¿ç¨‹è¢«æ‹’ç»�时会调用RejectedExecutionHandlerçš„rejectedExecution法。默认是抛出一个è¿�è¡Œæ—¶å¼‚å¸¸ã€‚çº¿ç¨‹æ± å¤§å°�设置需è¦�分æ��çº¿ç¨‹æ± æ‰§è¡Œçš„ä»»åŠ¡çš„ç‰¹æ€§ CPU 密集å�‹è¿˜æ˜¯ IO 密集å�‹æ¯�个任务执行的平å�‡æ—¶é•¿å¤§æ¦‚是多少这个任务的执行时长å�¯èƒ½è¿˜è·Ÿä»»åС处ç�†é€»è¾‘是å�¦æ¶‰å�Šåˆ°ç½‘ç»œä¼ è¾“ä»¥å�Šåº•层系统资æº�ä¾�赖有关系如æ�œæ˜¯ CPU 密集å�‹ä¸»è¦�是执行计算任务å“�应时间很快cpu 一直在è¿�行这ç§�任务 cpu的利用ç�‡å¾ˆé«˜é‚£ä¹ˆçº¿ç¨‹æ•°çš„é…�ç½®åº”è¯¥æ ¹æ�® CPU æ ¸å¿ƒæ•°æ�¥å†³å®šCPU æ ¸å¿ƒæ•°æœ€å¤§å�Œæ—¶æ‰§è¡Œçº¿ç¨‹æ•°åŠ å…¥ CPU æ ¸å¿ƒæ•°ä¸º 4那么æœ�务器最多能å�Œæ—¶æ‰§è¡Œ 4 个线程。过多的线程会导致上下文切æ�¢å��而使得效ç�‡é™�ä½�ã€‚é‚£çº¿ç¨‹æ± çš„æœ€å¤§çº¿ç¨‹æ•°å�¯ä»¥é…�置为 cpu æ ¸å¿ƒæ•°1 如æ�œæ˜¯ IO 密集å�‹ä¸»è¦�是进行 IO æ“�作执行 IO æ“�作的时间较长这是 cpu 出äº�空闲状æ€�导致 cpu 的利用ç�‡ä¸�高这ç§�情况下å�¯ä»¥å¢�åŠ çº¿ç¨‹æ± çš„å¤§å°�。这ç§�情况下å�¯ä»¥ç»“å�ˆçº¿ç¨‹çš„ç‰å¾…æ—¶é•¿æ�¥å�šåˆ¤æ–ç‰å¾…时间越高那么线程数也相对越多。一般å�¯ä»¥é…�ç½® cpu æ ¸å¿ƒæ•°çš„ 2 å€�。一个公å¼�çº¿ç¨‹æ± è®¾å®šæœ€ä½³çº¿ç¨‹æ•°ç›® çº¿ç¨‹æ± è®¾å®šçš„çº¿ç¨‹ç‰å¾…时间线程 CPU æ—¶é—´/线程 CPU æ—¶é—´ * CPU 数目这个公å¼�的线程 cpu 时间是预估的程åº�å�•个线程在 cpu 上è¿�行的时间通常使用 loadrunner测试大é‡�è¿�行次数求出平å�‡å€¼æ‹’ç»�ç–ç•¥AbortPolicyç›´æ�¥æŠ›å‡ºå¼‚常默认ç–ç•¥CallerRunsPolicy用调用者所在的线程æ�¥æ‰§è¡Œä»»åŠ¡DiscardOldestPolicy丢弃阻å¡�队列ä¸é� 最å‰�的任务并执行当å‰�任务DiscardPolicyç›´æ�¥ä¸¢å¼ƒä»»åŠ¡å½“ç„¶ä¹Ÿå�¯ä»¥æ ¹æ�®åº”用场景å®�ç�° RejectedExecutionHandler æ�¥å�£è‡ªå®šä¹‰é¥±å’Œç–略如记录日志或æŒ�久化å˜å‚¨ä¸�能处ç�†çš„任务10ã€�常è§�线程安全的并å�‘容器有哪些 难度系数â�CopyOnWriteArrayListã€�CopyOnWriteArraySetã€�ConcurrentHashMapCopyOnWriteArrayListã€�CopyOnWriteArraySet采用写时å¤�制å®�ç�°çº¿ç¨‹å®‰å…¨ConcurrentHashMap采用分段é”�的方å¼�å®�ç�°çº¿ç¨‹å®‰å…¨11ã€�Atomicå�Ÿå�类了解多少 å�Ÿç�†æ˜¯ä»€ä¹ˆ 难度系数â�Java çš„å�Ÿå�ç±»éƒ½å˜æ”¾åœ¨å¹¶å�‘包 java.util.concurrent.atomic下如下图基本类å�‹ä½¿ç”¨å�Ÿå�的方å¼�更新基本类å�‹AtomicIntegeræ•´å�‹å�Ÿå�ç±»AtomicLongé•¿æ•´å�‹å�Ÿå�ç±»AtomicBoolean布尔å�‹å�Ÿå�类数组类å�‹ä½¿ç”¨å�Ÿå�的方å¼�更新数组里的æŸ�ä¸ªå…ƒç´ AtomicIntegerArray整形数组å�Ÿå�ç±»AtomicLongArray长整形数组å�Ÿå�ç±»AtomicReferenceArray引用类å�‹æ•°ç»„å�Ÿå�类引用类å�‹AtomicReference引用类å�‹å�Ÿå�ç±»AtomicStampedReferenceå�Ÿå�更新引用类å�‹é‡Œçš„å—æ®µå�Ÿå�ç±»AtomicMarkableReference å�Ÿå�æ›´æ–°å¸¦æœ‰æ ‡è®°ä½�的引用类å�‹AtomicIntegerFieldUpdaterå�Ÿå�æ›´æ–°æ•´å½¢å—æ®µçš„æ›´æ–°å™¨AtomicLongFieldUpdaterå�Ÿå�æ›´æ–°é•¿æ•´å½¢å—æ®µçš„æ›´æ–°å™¨AtomicStampedReferenceå�Ÿå�更新带有版本å�·çš„引用类å�‹ã€‚该类将整数值ä¸�引用关è�”èµ·æ�¥å�¯ç”¨äº�解决å�Ÿå�的更新数æ�®å’Œæ•°æ�®çš„版本å�·ä»¥å�Šè§£å†³ä½¿ç”¨ CAS 进行å�Ÿå�æ›´æ–°æ—¶å�¯èƒ½å‡ºç�°çš„ ABA 问题AtomicInteger 类利用 CAS (Compare and Swap) volatile native 方法æ�¥ä¿�è¯�å�Ÿå�æ“�作ä»�而é�¿å…� synchronized 的高开销执行效ç�‡å¤§ä¸ºæ��å�‡ã€‚CAS çš„å�Ÿç�†æ˜¯æ‹¿æœŸæœ›å€¼å’Œå�Ÿæœ¬çš„值作比较如æ�œç›¸å�Œåˆ™æ›´æ–°æˆ�新的值。UnSafe 类的 objectFieldOffset() 方法是个本地方法这个方法是用æ�¥æ‹¿â€œå�Ÿå€¼â€�的内å˜åœ°å�€è¿”å›�值是 valueOffsetå�¦å¤–value 是一个 volatile å�˜é‡�å› æ¤ JVM 总是å�¯ä»¥ä¿�è¯�ä»»æ„�时刻的任何线程总能拿到该å�˜é‡�的最新值。12ã€�synchronized底层å®�ç�°æ˜¯ä»€ä¹ˆ lock底层是什么 有什么区别 难度系数â�â�â�Synchronizedå�Ÿç�†æ–¹æ³•级的å�Œæ¥æ˜¯éš�å¼�å�³æ— 需通过å—节ç �指令æ�¥æ�§åˆ¶çš„它å®�ç�°åœ¨æ–¹æ³•调用和返å›�æ“�作之ä¸ã€‚JVMå�¯ä»¥ä»�方法常é‡�æ± ä¸çš„æ–¹æ³•表结æ�„(method_info Structure) ä¸çš„ ACC_SYNCHRONIZED è®¿é—®æ ‡å¿—åŒºåˆ†ä¸€ä¸ªæ–¹æ³•æ˜¯å�¦å�Œæ¥æ–¹æ³•。当方法调用时调用指令将会 检查方法的 ACC_SYNCHRONIZED è®¿é—®æ ‡å¿—æ˜¯å�¦è¢«è®¾ç½®å¦‚æ�œè®¾ç½®äº†æ‰§è¡Œçº¿ç¨‹å°†å…ˆæŒ�有monitor虚拟机规范ä¸ç”¨çš„æ˜¯ç®¡ç¨‹ä¸€è¯�ç„¶å��å†�执行方法最å��å†�方法完æˆ�(æ— è®ºæ˜¯æ£å¸¸å®Œæˆ�还是é��æ£å¸¸å®Œæˆ�)时释放monitor。代ç �å�—çš„å�Œæ¥æ˜¯åˆ©ç”¨monitorenterå’Œmonitorexit这两个å—节ç �指令。它们分别ä½�äº�å�Œæ¥ä»£ç �å�—的开始和结æ�Ÿä½�置。当jvm执行到monitorenter指令时当å‰�线程试图è�·å�–monitor对象的所有æ�ƒå¦‚æ�œæœªåŠ é”�或者已ç»�被当å‰�线程所æŒ�有就把é”�的计数器1当执行monitorexit指令时é”�计数器-1当é”�计数器为0时该é”�就被释放了。如æ�œè�·å�–monitor对象失败该线程则会进入阻å¡�状æ€�直到其他线程释放é”�。Lockå�Ÿç�†Lockçš„å˜å‚¨ç»“æ�„一个intç±»å�‹çжæ€�值用äº�é”�的状æ€�å�˜æ›´ä¸€ä¸ªå�Œå�‘链表用äº�å˜å‚¨ç‰å¾…ä¸çš„线程Lockè�·å�–é”�的过程本质上是通过CASæ�¥è�·å�–状æ€�值修改如æ�œå½“场没è�·å�–到会将该线程放在线程ç‰å¾…链表ä¸ã€‚Lock释放é”�的过程修改状æ€�值调整ç‰å¾…链表。Lock大é‡�使用CASè‡ªæ—‹ã€‚å› æ¤æ ¹æ�®CAS特性lock建议使用在ä½�é”�冲çª�的情况下。Lockä¸�synchronized的区别Lockçš„åŠ é”�和解é”�都是由java代ç �é…�å�ˆnative方法调用æ“�作系统的相关方法å®�ç�°çš„而synchronizeçš„åŠ é”�和解é”�的过程是由JVM管ç�†çš„当一个线程使用synchronizeè�·å�–é”�æ—¶è‹¥é”�被其他线程å� 用ç�€é‚£ä¹ˆå½“å‰�å�ªèƒ½è¢«é˜»å¡�直到æˆ�功è�·å�–é”�。而Lock则æ��供超时é”�å’Œå�¯ä¸æ–ç‰æ›´åŠ ç�µæ´»çš„æ–¹å¼�在未能è�·å�–é”�çš„ æ�¡ä»¶ä¸‹æ��供一ç§�退出的机制。一个é”�内部å�¯ä»¥æœ‰å¤šä¸ªConditionå®�例å�³æœ‰å¤šè·¯æ�¡ä»¶é˜Ÿåˆ—而synchronizeå�ªæœ‰ä¸€è·¯æ�¡ä»¶é˜Ÿåˆ—å�Œæ ·Condition也æ��ä¾›ç�µæ´»çš„阻å¡�æ–¹å¼�在未è�·å¾—通知之å‰�å�¯ä»¥é€šè¿‡ä¸æ–线程以 å�Šè®¾ç½®ç‰å¾…æ—¶é™�ç‰æ–¹å¼�退出æ�¡ä»¶é˜Ÿåˆ—。synchronize对线程的å�Œæ¥ä»…æ��供独å� 模å¼�而Lockå�³å�¯ä»¥æ��供独å� 模å¼�也å�¯ä»¥æ��供共享模å¼�synchronizedLock关键å—ç±»è‡ªåŠ¨åŠ é”�和释放é”�需è¦�手动调用unlock方法释放é”�jvm层é�¢çš„é”�API层é�¢çš„é”�é��公平é”�å�¯ä»¥é€‰æ‹©å…¬å¹³æˆ–者é��公平é”�é”�是一个对象,并且é”�的信æ�¯ä¿�å˜åœ¨äº†å¯¹è±¡ä¸ä»£ç �ä¸é€šè¿‡intç±»å�‹çš„stateæ ‡è¯†æœ‰ä¸€ä¸ªé”�å�‡çº§çš„è¿‡ç¨‹æ— 13ã€�了解ConcurrentHashMapå�— 为什么性能比HashTable高说下å�Ÿç�† 难度系数â�â�ConcurrentHashMap是线程安全的Map容器JDK8之å‰�ConcurrentHashMap使用é”�分段技术将数æ�®åˆ†æˆ�一段段å˜å‚¨æ¯�个数æ�®æ®µé…�置一把é”�å�³segment类这个类继承ReentrantLockæ�¥ä¿�è¯�线程安全JKD8的版本å�–消Segment这个分段é”�æ•°æ�®ç»“æ�„底层也是使用Nodeæ•°ç»„é“¾è¡¨çº¢é»‘æ ‘ä»�而å®�ç�°å¯¹æ¯�一段数æ�®å°±è¡ŒåŠ é”�也å‡�少了并å�‘冲çª�的概ç�‡ã€‚hashtable类基本上所有的方法都是采用synchronized进行线程安全æ�§åˆ¶é«˜å¹¶å�‘情况下效ç�‡å°±é™�ä½� ConcurrentHashMap是采用了分段é”�çš„æ€�想æ��高性能é”�粒度更细化14ã€�ConcurrentHashMap底层å�Ÿç�† 难度系数â�â�â�Java7 ä¸ ConcurrentHashMap 使用的分段é”�也就是æ¯�一个 Segment 上å�Œæ—¶å�ªæœ‰ä¸€ä¸ªçº¿ç¨‹å�¯ä»¥æ“�作æ¯�一个 Segment 都是一个类似 HashMap 数组的结æ�„它å�¯ä»¥æ‰©å®¹å®ƒçš„冲çª�会转化为链表。但是 Segment 的个数一但åˆ�始化就ä¸�能改å�˜ã€‚public V put(K key, V value) {SegmentK,V s;if (value null)throw new NullPointerException();int hash hash(key);// hash å€¼æ— ç¬¦å�·å�³ç§» 28ä½�åˆ�始化时è�·å¾—ç„¶å��ä¸� segmentMask15 å�šä¸�è¿�ç®—// å…¶å®�也就是把高4ä½�ä¸�segmentMask1111å�šä¸�è¿�ç®—// this.segmentMask ssize - 1;//对hash值进行å�³ç§»segmentShiftä½�è®¡ç®—å…ƒç´ å¯¹åº”segment䏿•°ç»„下表的ä½�ç½®//把hashå�³ç§»segmentShift相当äº�å�ªè¦�hash值的高32-segmentShiftä½�å�³ç§»çš„目的是ä¿�留了hash值的高ä½�。然å��å’ŒsegmentMaskä¸�æ“�ä½œè®¡ç®—å…ƒç´ åœ¨segment数组ä¸çš„下表int j (hash segmentShift) segmentMask;//使用unsafe对象è�·å�–数组ä¸ç¬¬j个ä½�置的值å��é�¢åŠ ä¸Šçš„æ˜¯å��ç§»é‡�if ((s (SegmentK,V)UNSAFE.getObject // nonvolatile; recheck(segments, (j SSHIFT) SBASE)) null) // in ensureSegment// 如æ�œæŸ¥æ‰¾åˆ°çš„ Segment 为空åˆ�始化s ensureSegment(j);//æ�’å…¥segment对象return s.put(key, hash, value, false);}/*** Returns the segment for the given index, creating it and* recording in segment table (via CAS) if not already present.** param k the index* return the segment*/SuppressWarnings(unchecked)private SegmentK,V ensureSegment(int k) {final SegmentK,V[] ss this.segments;long u (k SSHIFT) SBASE; // raw offsetSegmentK,V seg;// åˆ¤æ– u ä½�置的 Segment 是å�¦ä¸ºnullif ((seg (SegmentK,V)UNSAFE.getObjectVolatile(ss, u)) null) {SegmentK,V proto ss[0]; // use segment 0 as prototype// è�·å�–0å�· segment 里的 HashEntryK,V åˆ�始化长度int cap proto.table.length;// è�·å�–0å�· segment 里的 hash è¡¨é‡Œçš„æ‰©å®¹è´Ÿè½½å› å�所有的 segment çš„ loadFactor 是相å�Œçš„float lf proto.loadFactor;// 计算扩容阀值int threshold (int)(cap * lf);// 创建一个 cap 容é‡�çš„ HashEntry 数组HashEntryK,V[] tab (HashEntryK,V[])new HashEntry[cap];if ((seg (SegmentK,V)UNSAFE.getObjectVolatile(ss, u)) null) { // recheck// å†�次检查 u ä½�置的 Segment 是å�¦ä¸ºnullå› ä¸ºè¿™æ—¶å�¯èƒ½æœ‰å…¶ä»–线程进行了æ“�作SegmentK,V s new SegmentK,V(lf, threshold, tab);// 自旋检查 u ä½�置的 Segment 是å�¦ä¸ºnullwhile ((seg (SegmentK,V)UNSAFE.getObjectVolatile(ss, u)) null) {// 使用CAS 赋值å�ªä¼šæˆ�功一次if (UNSAFE.compareAndSwapObject(ss, u, null, seg s))break;}}}return seg;}final V put(K key, int hash, V value, boolean onlyIfAbsent) {// è�·å�– ReentrantLock 独å� é”�è�·å�–ä¸�到scanAndLockForPut è�·å�–。HashEntryK,V node tryLock() ? null : scanAndLockForPut(key, hash, value);V oldValue;try {HashEntryK,V[] tab table;// 计算è¦�put的数æ�®ä½�ç½®int index (tab.length -
hash;// CAS è�·å�– index å��æ ‡çš„å€¼HashEntryK,V first entryAt(tab, index);for (HashEntryK,V e first;;) {if (e ! null) {// 检查是å�¦ key å·²ç»�å˜åœ¨å¦‚æ�œå˜åœ¨åˆ™é��å�†é“¾è¡¨å¯»æ‰¾ä½�置找到å��替æ�¢ valueK k;if ((k e.key) key ||(e.hash hash key.equals(k))) {oldValue e.value;if (!onlyIfAbsent) {e.value value;modCount;}break;}e e.next;}else {// first 有值没说æ˜� index ä½�置已ç»�有值了有冲çª�链表头æ�’法。if (node ! null)node.setNext(first);elsenode new HashEntryK,V(hash, key, value, first);int c count 1;// 容é‡�大äº�扩容阀值å°�äº�最大容é‡�进行扩容if (c threshold tab.length MAXIMUM_CAPACITY)rehash(node);else// index ä½�置赋值 nodenode å�¯èƒ½æ˜¯ä¸€ä¸ªå…ƒç´ 也å�¯èƒ½æ˜¯ä¸€ä¸ªé“¾è¡¨çš„表头setEntryAt(tab, index, node);modCount;count c;oldValue null;break;}}} finally {unlock();}return oldValue;}JavaJava8 ä¸çš„ ConcurrentHashMap 使用的 Synchronized é”�åŠ CAS 的机制。结æ�„Node 数组 链表 / çº¢é»‘æ ‘Node 是类似äº�一个 HashEntry 的结æ�„。它的冲çª�å†�达到一定大å°�时会转化æˆ�çº¢é»‘æ ‘åœ¨å†²çª�å°�äº�一定数é‡�æ—¶å�ˆé€€å›�链表。public V put(K key, V value) {return putVal(key, value, false);}/** Implementation for put and putIfAbsent */final V putVal(K key, V value, boolean onlyIfAbsent) {// key å’Œ value ä¸�能为空if (key null || value null) throw new NullPointerException();int hash spread(key.hashCode());int binCount 0;for (NodeK,V[] tab table;;) {// f ç›®æ ‡ä½�ç½®å…ƒç´ NodeK,V f; int n, i, fh;// fh å��é�¢å˜æ”¾ç›®æ ‡ä½�ç½®çš„å…ƒç´ hash 值if (tab null || (n tab.length)
// 数组桶为空�始化数组桶自旋CAS)tab initTable();else if ((f tabAt(tab, i (n -
hash)) null) {// 桶内为空CAS 放入ä¸�åŠ é”�æˆ�功了就直æ�¥ break 跳出if (casTabAt(tab, i, null,new NodeK,V(hash, key, value, null)))break; // no lock when adding to empty bin}else if ((fh f.hash) MOVED)tab helpTransfer(tab, f);else {V oldVal null;// 使用 synchronized åŠ é”�åŠ å…¥èŠ‚ç‚¹synchronized (f) {if (tabAt(tab, i) f) {// 说æ˜�是链表if (fh
{binCount 1;// 循ç�¯åŠ å…¥æ–°çš„æˆ–è€…è¦†ç›–èŠ‚ç‚¹for (NodeK,V e f;; binCount) {K ek;if (e.hash hash ((ek e.key) key ||(ek ! null key.equals(ek)))) {oldVal e.val;if (!onlyIfAbsent)e.val value;break;}NodeK,V pred e;if ((e e.next) null) {pred.next new NodeK,V(hash, key,value, null);break;}}}else if (f instanceof TreeBin) {// çº¢é»‘æ ‘NodeK,V p;binCount 2;if ((p ((TreeBinK,V)f).putTreeVal(hash, key,value)) ! null) {oldVal p.val;if (!onlyIfAbsent)p.val value;}}}}if (binCount !
{if (binCount TREEIFY_THRESHOLD)treeifyBin(tab, i);if (oldVal ! null)return oldVal;break;}}}addCount(1L, binCount);return null;}15ã€�了解volatile关键å—ä¸� 难度系数â�volatile是Javaæ��供的最轻é‡�级的å�Œæ¥æœºåˆ¶ä¿�è¯�了共享å�˜é‡�çš„å�¯è§�性被volatile关键å—修饰的å�˜é‡�如æ�œå€¼å�‘生了å�˜åŒ–其他线程立刻å�¯è§�é�¿å…�出ç�°è„�读ç�°è±¡ã€‚volatileç¦�æ¢äº†æŒ‡ä»¤é‡�æ�’å�¯ä»¥ä¿�è¯�程åº�执行的有åº�性但是由äº�ç¦�æ¢äº†æŒ‡ä»¤é‡�æ�’所以JVM相关的优化没了效ç�‡ä¼šå��å¼±16ã€�synchronizedå’Œvolatile有什么区别 难度系数â�â�volatile本质是告诉JVM当å‰�å�˜é‡�在寄å˜å™¨ä¸çš„值是ä¸�确定的需è¦�ä»�主å˜ä¸è¯»å�–synchronized则是é”�定当å‰�å�˜é‡�å�ªæœ‰å½“å‰�线程å�¯ä»¥è®¿é—®è¯¥å�˜é‡�其他线程被阻å¡�ä½�。volatile仅能用在å�˜é‡�级别而synchronizedå�¯ä»¥ä½¿ç”¨åœ¨å�˜é‡�ã€�方法ã€�类级别。volatile仅能å®�ç�°å�˜é‡�的修改å�¯è§�性ä¸�能ä¿�è¯�å�Ÿå�性而synchronized则å�¯ä»¥ä¿�è¯�å�˜é‡�的修改å�¯è§�性和å�Ÿå�性。volatileä¸�ä¼šé€ æˆ�线程阻å¡�synchronizedå�¯èƒ½ä¼šé€ æˆ�线程阻å¡�。volatileæ ‡è®°çš„å�˜é‡�ä¸�会被编译器优化synchronizedæ ‡è®°çš„å�˜é‡�å�¯ä»¥è¢«ç¼–译器优化。
免费b站看大片真人电视剧免费调-免费b站看大片真人电视剧免费调应用