8x换新地址了么

核心内容摘要

时代变迁下的“男困困”与“女困困”:一部剧照进现实的共鸣
罗马假日?不,这是“王者”家庭的温馨日常!孙尚香辅导刘禅,解锁育儿新姿势!

9.1免费版安装版:开启无限可能,效率与创新的完美融合

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æ ‡è®°çš„å�˜é‡�å�¯ä»¥è¢«ç¼–译器优化。

9.1国内nba免费-9.1国内nba免费应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123