(PSï¼æ«æ[é¦é¡µéé¢çäºç»´ç ](README.md)è¿ç¾¤ï¼å享æèªå·±å¨ççææ¯èµæç»å¤§å®¶ï¼å¸æå大家ä¸èµ·å¦ä¹ è¿æ¥ï¼)
# å¤çº¿ç¨ä¸é¢
#### [1.è¿ç¨ä¸çº¿ç¨çåºå«æ¯ä»ä¹ï¼](#è¿ç¨ä¸çº¿ç¨çåºå«æ¯ä»ä¹ï¼)
#### [2.è¿ç¨é´å¦ä½éä¿¡ï¼](#è¿ç¨é´å¦ä½éä¿¡ï¼)
#### [3.Javaä¸å便åªäºåæ³ï¼](#Javaä¸å便åªäºåæ³ï¼)
#### [4.Javaä¸åå»ºçº¿ç¨æåªäºæ¹å¼?](#Javaä¸åå»ºçº¿ç¨æåªäºæ¹å¼?)
#### [5.å¦ä½è§£å³åºååæ¶å¯ä»¥å建åºåä¾å¯¹è±¡çé®é¢?](#å¦ä½è§£å³åºååæ¶å¯ä»¥å建åºåä¾å¯¹è±¡çé®é¢?)
#### [6.volatileå
³é®åæä»ä¹ç¨ï¼æä¹çè§£å¯è§æ§ï¼ä¸è¬ä»ä¹åºæ¯å»ç¨å¯è§æ§ï¼](#volatileå
³é®åæä»ä¹ç¨ï¼æä¹çè§£å¯è§æ§ï¼ä¸è¬ä»ä¹åºæ¯å»ç¨å¯è§æ§ï¼)
#### [7.Javaä¸çº¿ç¨çç¶ææ¯æä¹æ ·çï¼](#Javaä¸çº¿ç¨çç¶ææ¯æä¹æ ·çï¼)
#### [8.wait()ï¼join()ï¼sleep()æ¹æ³æä»ä¹ä½ç¨ï¼](#wait()ï¼join()ï¼sleep()æ¹æ³æä»ä¹ä½ç¨ï¼)
#### [9.Thread.sleep(),Object.wait(),LockSupport.park()æä»ä¹åºå«ï¼](#Thread.sleep(),Object.wait(),LockSupport.park()æä»ä¹åºå«ï¼)
#### [10.è°ä¸è°ä½ 对线ç¨ä¸æççè§£ï¼](#è°ä¸è°ä½ 对线ç¨ä¸æççè§£ï¼)
#### [11.线ç¨é´æä¹éä¿¡ï¼](#线ç¨é´æä¹éä¿¡ï¼)
#### [12.æä¹å®ç°å®ç°ä¸ä¸ªç产è
æ¶è´¹è
ï¼](#æä¹å®ç°å®ç°ä¸ä¸ªç产è
æ¶è´¹è
ï¼)
#### [13.è°ä¸è°ä½ å¯¹çº¿ç¨æ± ççè§£ï¼](#è°ä¸è°ä½ å¯¹çº¿ç¨æ± ççè§£ï¼)
#### [14.çº¿ç¨æ± æåªäºç¶æï¼](#çº¿ç¨æ± æåªäºç¶æï¼)
### è¿ç¨ä¸çº¿ç¨çåºå«æ¯ä»ä¹ï¼
#### æ¹å¤çæä½ç³»ç»
**æ¹å¤çæä½ç³»ç»**å°±æ¯æä¸ç³»åéè¦æä½çæä»¤å䏿¥ï¼å½¢æä¸ä¸ªæ¸
åï¼ä¸æ¬¡æ§äº¤ç»è®¡ç®æºãç¨æ·å°å¤ä¸ªéè¦æ§è¡çç¨åºåå¨ç£å¸¦ä¸ï¼ç¶å交ç±è®¡ç®æºå»è¯»åå¹¶é个æ§è¡è¿äºç¨åºï¼å¹¶å°è¾åºç»æåå¨å¦ä¸ä¸ªç£å¸¦ä¸ã
æ¹å¤çæä½ç³»ç»å¨ä¸å®ç¨åº¦ä¸æé«äºè®¡ç®æºçæçï¼ä½æ¯ç±äº**æ¹å¤çæä½ç³»ç»çæä»¤è¿è¡æ¹å¼ä»ç¶æ¯ä¸²è¡çï¼å
åä¸å§ç»åªæä¸ä¸ªç¨åºå¨è¿è¡**ï¼åé¢çç¨åºéè¦çå¾
åé¢çç¨åºæ§è¡å®æåæè½å¼å§æ§è¡ï¼èåé¢çç¨åºææ¶ä¼ç±äºI/Oæä½ãç½ç»çåå é»å¡ï¼å¯¼è´CPUé²ç½®æä»¥**æ¹å¤çæä½æçä¹ä¸é«**ã
#### è¿ç¨çæåº
æ¹å¤çæä½ç³»ç»çç¶é¢å¨äºå
åä¸åªåå¨ä¸ä¸ªç¨åºï¼è¿ç¨çæåºï¼å¯ä»¥è®©å
åä¸åå¨å¤ä¸ªç¨åºï¼æ¯ä¸ªç¨åºå¯¹åºä¸ä¸ªè¿ç¨ï¼è¿ç¨æ¯æä½ç³»ç»èµæºåé
çæå°åä½ãCPUéç¨æ¶é´çè½®è½¬çæ¹å¼è¿è¡è¿ç¨ï¼CPU为æ¯ä¸ªè¿ç¨åé
ä¸ä¸ªæ¶é´æ®µï¼ç§°ä½å®çæ¶é´çã妿卿¶é´çç»ææ¶è¿ç¨è¿å¨è¿è¡ï¼åæåè¿ä¸ªè¿ç¨çè¿è¡ï¼å¹¶ä¸CPUåé
ç»å¦ä¸ä¸ªè¿ç¨ï¼è¿ä¸ªè¿ç¨å«åä¸ä¸æåæ¢ï¼ã妿è¿ç¨å¨æ¶é´çç»æåé»å¡æç»æï¼åCPUç«å³è¿è¡åæ¢ï¼ä¸ç¨çå¾
æ¶é´çç¨å®ãå¤è¿ç¨ç好å¤å¨äºä¸ä¸ªå¨è¿è¡IOæä½æ¶å¯ä»¥è®©åºCPUæ¶é´çï¼è®©CPUæ§è¡å
¶ä»è¿ç¨çä»»å¡ã
#### 线ç¨çæåº
éçè®¡ç®æºçåå±ï¼å¯¹CPUçè¦æ±è¶æ¥è¶é«ï¼è¿ç¨ä¹é´ç忢å¼éè¾å¤§ï¼å·²ç»æ æ³æ»¡è¶³è¶æ¥è¶å¤æçç¨åºçè¦æ±äºãäºæ¯å°±åæäºçº¿ç¨ï¼çº¿ç¨æ¯ç¨åºæ§è¡ä¸ä¸ä¸ªåä¸çé¡ºåºæ§å¶æµç¨ï¼æ¯ç¨åºæ§è¡æµçæå°åå
ï¼æ¯å¤çå¨è°åº¦ååæ´¾çåºæ¬åä½ãä¸ä¸ªè¿ç¨å¯ä»¥æä¸ä¸ªæå¤ä¸ªçº¿ç¨ï¼å个线ç¨ä¹é´å
±äº«ç¨åºçå
å空é´(ä¹å°±æ¯æå¨è¿ç¨çå
å空é´)ã
#### è¿ç¨å线ç¨çåºå«
è¿ç¨æ¯è®¡ç®æºä¸å·²è¿è¡ç¨åºçå®ä½ï¼è¿ç¨æ¯æä½ç³»ç»èµæºåé
çæå°åä½ãèçº¿ç¨æ¯å¨è¿ç¨ä¸æ§è¡çä¸ä¸ªä»»å¡ï¼æ¯CPUè°åº¦åæ§è¡çæå°åä½ãä»ä»¬ä¸¤ä¸ªæ¬è´¨çåºå«æ¯æ¯å¦**åç¬å æå
åå°å空é´åå
¶å®ç³»ç»èµæºï¼æ¯å¦I/Oï¼**ï¼
* è¿ç¨åç¬å æä¸å®çå
åå°å空é´ï¼æä»¥è¿ç¨é´åå¨å
åéç¦»ï¼æ°æ®æ¯åå¼çï¼æ°æ®å
±äº«å¤æä½æ¯åæ¥ç®åï¼å个è¿ç¨ä¹é´äºä¸å¹²æ°ï¼è线ç¨å
±äº«æå±è¿ç¨å æçå
åå°å空é´åèµæºï¼æ°æ®å
±äº«ç®åï¼ä½æ¯åæ¥å¤æã
* è¿ç¨åç¬å æä¸å®çå
åå°å空é´ï¼ä¸ä¸ªè¿ç¨åºç°é®é¢ä¸ä¼å½±åå
¶ä»è¿ç¨ï¼ä¸å½±å主ç¨åºçç¨³å®æ§ï¼å¯é æ§é«ï¼ä¸ä¸ªçº¿ç¨å´©æºå¯è½å½±åæ´ä¸ªç¨åºçç¨³å®æ§ï¼å¯é æ§è¾ä½ã
* è¿ç¨åç¬å æä¸å®çå
åå°å空é´ï¼è¿ç¨çå建å鿝ä¸ä»
éè¦ä¿åå¯åå¨åæ ä¿¡æ¯ï¼è¿éè¦èµæºçåé
忶以å页è°åº¦ï¼å¼éè¾å¤§ï¼çº¿ç¨åªéè¦ä¿åå¯åå¨åæ ä¿¡æ¯ï¼å¼éè¾å°ã
å¦å¤ä¸ä¸ªéè¦åºå«æ¯ï¼è¿ç¨æ¯æä½ç³»ç»è¿è¡èµæºåé
çåºæ¬åä½ï¼èçº¿ç¨æ¯æä½ç³»ç»è¿è¡è°åº¦çåºæ¬åä½ï¼å³CPUåé
æ¶é´çåä½ ã
#### ç¬ç«æ§
Linuxç³»ç»ä¼ç»æ¯ä¸ªè¿ç¨åé
4Gçèæå°å空é´(0å°3Gæ¯Userå°å空é´ï¼3å°4Gé¨åæ¯kernelå°å空é´)ï¼è¿ç¨å
·å¤ç§æçå°å空é´ï¼æªç»å
许ï¼ä¸ä¸ªç¨æ·è¿ç¨ä¸è½è®¿é®å
¶ä»è¿ç¨çå°å空é´ã
#### 卿æ§
ç¨åºæ¯ä¸ä¸ªéæçæä»¤éåï¼èè¿ç¨æ¯æ£å¨æä½ç³»ç»ä¸è¿è¡çæä»¤éåï¼è¿ç¨æèªå·±ççå½å¨æååç§ä¸åçç¶æã
äºææ¨¡åä¸è¬æçæ¯:
**æ°å»ºæ**ï¼å建ä¸ä¸ªè¿ç¨ï¼
**就绪æ**ï¼å·²ç»è·åå°èµæºï¼åå¤å¥½äºï¼è¿å
¥è¿è¡éåï¼ä¸æ¦è·å¾æ¶é´çå¯ä»¥ç«å³æ§è¡ï¼
**è¿è¡æ**ï¼è·åå°äºæ¶é´çï¼æ§è¡ç¨åºï¼
**é»å¡æ**ï¼è¿è¡è¿ç¨ä¸çå¾
è·åå
¶ä»èµæºï¼I/O请æ±çï¼
**ç»æ¢æ**ï¼è¿ç¨è¢«ææ»äº)
#### å¹¶åæ§
å¤ä¸ªè¿ç¨å¯ä»¥å¨CPUä¸å¹¶åæ§è¡ã
çº¿ç¨æ¯ç¬ç«è¿è¡åè°åº¦çæå°åä½ï¼çº¿ç¨ä¼å
±äº«è¿ç¨çèæç©ºé´ï¼ä¸ä¸ªè¿ç¨ä¼å¯¹åºå¤ä¸ªçº¿ç¨ãå¨Javaä¸ï¼çº¿ç¨æ¥æèªå·±ç§æçç¨åºè®¡æ°å¨ï¼èææºæ ï¼æ¬å°æ¹æ³æ ã
#### PS:èæå
å
èæå
忝ä¸ç§é»è¾ä¸æ©å
ç©çå
åçææ¯ãåºæ¬ææ³æ¯ç¨è½¯ãç¡¬ä»¶ææ¯æå
åä¸å¤åè¿ä¸¤çº§åå¨å¨å½åä¸çº§åå¨å¨æ¥ç¨ãèæå
åææ¯çå®ç°å©ç¨äºèªå¨è¦çåäº¤æ¢ææ¯ãç®åç说就æ¯å°ç¡¬ççä¸é¨åä½ä¸ºå
åæ¥ä½¿ç¨ã
#### PS:èæå°å空é´
æ¯ä¸ªè¿ç¨æ4Gçå°å空é´ï¼å¨è¿è¡ç¨åºæ¶ï¼åªæä¸é¨åæ°æ®æ¯çæ£å è½½å°å
åä¸çï¼å
å管çåå
å°èæå°å转æ¢ä¸ºç©çå°åï¼å¦æå
åä¸ä¸åå¨è¿é¨åæ°æ®ï¼é£ä¹ä¼ä½¿ç¨é¡µé¢ç½®æ¢æ¹æ³ï¼å°å
å页置æ¢åºæ¥ï¼ç¶åå°å¤åä¸çæ°æ®å å
¥å°å
åä¸ï¼ä½¿å¾ç¨åºæ£å¸¸è¿è¡ã
### è¿ç¨é´å¦ä½éä¿¡ï¼
è¿ç¨é´éä¿¡çæ¹å¼ä¸»è¦æç®¡éï¼
#### 管é
è°ç¨pipe彿°å¨å
åä¸å¼è¾ä¸åç¼å²åºï¼ç®¡éååå·¥çï¼å³æ°æ®åªè½å¨ä¸ä¸ªæ¹å䏿µå¨ï¼ï¼å
·æåºå®ç读端åå端ï¼è°ç¨
```
#include
int pipe(int pipefd[2]);
```
### Javaä¸åå»ºçº¿ç¨æåªäºæ¹å¼?
#### 第ä¸ç§ ç»§æ¿Threadç±»ï¼éåRunæ¹æ³
è¿ç§æ¹æ³å°±æ¯éè¿èªå®ä¹CustomThread类继æ¿Threadç±»ï¼éårun()æ¹æ³ï¼ç¶åå建CustomThreadç对象ï¼ç¶åè°ç¨start()æ¹æ³ï¼JVMä¼å建åºä¸ä¸ªæ°çº¿ç¨ï¼å¹¶ä¸ä¸ºçº¿ç¨åå»ºæ¹æ³è°ç¨æ åç¨åºè®¡æ°å¨ï¼æ¤æ¶çº¿ç¨å¤äºå°±ç»ªç¶æï¼å½çº¿ç¨è·åCPUæ¶é´çåï¼çº¿ç¨ä¼è¿å
¥å°è¿è¡ç¶æï¼ä¼å»è°ç¨run()æ¹æ³ãå¹¶ä¸å建CustomThreadç±»ç对象ç线ç¨(è¿éçä¾å䏿¯ä¸»çº¿ç¨)ä¸è°ç¨run()æ¹æ³ç线ç¨ä¹é´æ¯å¹¶åçï¼ä¹å°±æ¯å¨æ§è¡run()æ¹æ³æ¶ï¼ä¸»çº¿ç¨å¯ä»¥å»æ§è¡å
¶ä»æä½ã
```java
class CustomThread extends Thread {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"线ç¨è°ç¨äºmainæ¹æ³");
for (int i = 0; i < 10; i++) {
if (i == 1) {
CustomThread customThread = new CustomThread();
customThread.start();
System.out.println(Thread.currentThread().getName()+"线ç¨--iæ¯"+i);
}
}
System.out.println("main()æ¹æ³æ§è¡å®æ¯ï¼");
}
void run() {
System.out.println(Thread.currentThread().getName()+"线ç¨è°ç¨äºrun()æ¹æ³");
for (int j = 0; j < 5; j++) {
System.out.println(Thread.currentThread().getName()+"线ç¨--jæ¯"+j);
}
System.out.println("run()æ¹æ³æ§è¡å®æ¯ï¼");
}
}
```
è¾åºç»æå¦ä¸ï¼
```
main线ç¨è°ç¨äºmainæ¹æ³
Thread-0线ç¨è°ç¨äºrun()æ¹æ³
Thread-0线ç¨--jæ¯0
main线ç¨--iæ¯1
Thread-0线ç¨--jæ¯2
Thread-0线ç¨--jæ¯3
Thread-0线ç¨--jæ¯4
run()æ¹æ³æ§è¡å®æ¯ï¼
main()æ¹æ³æ§è¡å®æ¯ï¼
```
å¯ä»¥çå°å¨å建ä¸ä¸ªCustomThread对象ï¼è°ç¨start()æ¹æ³åï¼Thread-0è°ç¨äºrunæ¹æ³ï¼è¿è¡for循ç¯ï¼å¯¹jè¿è¡æå°ï¼ä¸æ¤åæ¶ï¼main线ç¨å¹¶æ²¡æè¢«é»å¡ï¼èæ¯ç»§ç»æ§è¡for循ç¯ï¼å¯¹iè¿è¡æå°ã
##### æ§è¡åç
é¦å
æä»¬å¯ä»¥æ¥ççstartçæºç ï¼é¦å
ä¼å¤æthreadStatusæ¯å¦ä¸º0ï¼å¦æä¸ä¸º0伿åºå¼å¸¸ãç¶åä¼å°å½å对象添å å°çº¿ç¨ç»ï¼æåè°ç¨start0æ¹æ³ï¼å 为æ¯nativeæ¹æ³ï¼çä¸å°æºç ï¼æ ¹æ®ä¸é¢çæ§è¡ç»ææ¥çï¼JVMæ°å»ºäºä¸ä¸ªçº¿ç¨è°ç¨äºrunæ¹æ³ã
```java
private native void start0();
public synchronized void start() {
//夿å½åThread对象æ¯å¦æ¯æ°å»ºæï¼å¦åæåºå¼å¸¸
if (threadStatus != 0)
throw new IllegalThreadStateException();
//å°å½å对象添å å°çº¿ç¨ç»
group.add(this);
boolean started = false;
try {
start0();//è¿æ¯ä¸ä¸ªnativeæ¹æ³ï¼è°ç¨åJVM伿°å»ºä¸ä¸ªçº¿ç¨æ¥è°ç¨runæ¹æ³
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
```
æ©å±é®é¢ï¼å¤æ¬¡è°ç¨Thread对象çstart()æ¹æ³ä¼æä¹æ ·ï¼
伿åºIllegalThreadStateExceptionå¼å¸¸ãå
¶å®å¨Thread#start()æ¹æ³éé¢ççæ³¨é䏿æå°ï¼å¤æ¬¡è°ç¨start()æ¹æ³æ¯éæ³çï¼æä»¥å¨ä¸é¢çstart()æ¹æ³æºç ä¸ä¸å¼å§å°±æ¯å¯¹threadStatusè¿è¡å¤æï¼ä¸ä¸º0就伿åºIllegalThreadStateExceptionå¼å¸¸ã

##### 注æäºé¡¹ï¼
start()æ¹æ³ä¸å¤æthreadStatusæ¯å¦ä¸º0ï¼æ¯å¤æå½åçº¿ç¨æ¯å¦æ°å»ºæï¼0æ¯ä»£è¡¨æ°å»ºæ(ä¸å¾ä¸çæºç 注éé颿æå°)ï¼è䏿¯å°±ç»ªæï¼å 为JavaçThreadç±»ä¸ï¼ThreadçRunnableç¶æå
æ¬äºçº¿ç¨ç就绪æåè¿è¡æï¼ï¼Threadçstate为RUNNABLEæ¶(ä¹å°±æ¯threadStatus为4æ¶)ï¼ä»£è¡¨çº¿ç¨ä¸ºå°±ç»ªææè¿è¡æï¼ãæ§è¡start()æ¹æ³ç线ç¨è¿ä¸æ¯JVMæ°å»ºç线ç¨ï¼æä»¥ä¸æ¯å°±ç»ªæãæä¸äºææ¯æç« æè¿éå¼éäºï¼ä¾å¦è¿ä¸ç¯[ãæ·±å
¥æµ
åºçº¿ç¨Threadç±»çstart()æ¹æ³årun()æ¹æ³ã](https://juejin.im/post/5b09274af265da0de25759d5)

##### æ»ç»
è¿ç§æ¹å¼ç缺ç¹å¾ææ¾ï¼å°±æ¯éè¦ç»§æ¿Threadç±»ï¼èä¸å®é
䏿们çéæ±å¯è½ä»
ä»
æ¯å¸ææäºæä½è¢«ä¸ä¸ªå
¶ä»ççº¿ç¨æ¥æ§è¡ï¼æä»¥æäºç¬¬äºç§æ¹æ³ã
#### 第äºç§ å®ç°Runnableæ¥å£
è¿ç§æ¹å¼å°±æ¯å建ä¸ä¸ªç±»(ä¾å¦ä¸é¢ä»£ç ä¸çTargetç±»)ï¼å®ç°Runnableæ¥å£çRunæ¹æ³ï¼ç¶åå°Targetç±»çå®ä¾å¯¹è±¡ä½ä¸ºThreadçæé å¨å
¥åtargetï¼å®é
ç线ç¨å¯¹è±¡è¿æ¯Threadå®ä¾ï¼åªä¸è¿çº¿ç¨Threadä¸çº¿ç¨æ§è¡ä½ï¼Targetç±»çrunæ¹æ³ï¼å离äºï¼è¦å度æ´ä½ä¸äºã
```java
class ThreadTarget implements Runnable {
void run() {
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºrunæ¹æ³");
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºmainæ¹æ³");
ThreadTarget target = new ThreadTarget();
Thread thread = new Thread(target);
thread.start();
}
}
```
è¾åºç»æå¦ä¸ï¼

##### åç
乿以æè¿ç§å®ç°æ¹æ³ï¼æ¯å 为Threadç±»çrun()æ¹æ³ä¸ä¼å¤ææååétargetæ¯å¦ä¸ºç©ºï¼ä¸ä¸ºç©ºå°±ä¼è°ç¨targetç±»çrunæ¹æ³ã
```java
private Runnable target;
public void run() {
if (target != null) {
target.run();
}
}
```
##### å¦å¤ä¸ç§åæ³
è¿ç§å®ç°æ¹å¼ä¹æå
¶ä»çåæ³ï¼å¯ä»¥ä¸å建Targetç±»ã
##### å¿åå
é¨ç±»
å¯ä»¥ä¸å建Targetç±»ï¼å¯ä»¥ä½¿ç¨å¿åå
é¨ç±»çæ¹å¼æ¥å®ç°ï¼å æ¤ä¸é¢ç代ç ä¹å¯ä»¥æä»¥ä¸æ¹å¼åï¼
```java
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºrunæ¹æ³");
}
});
thread.start();
```
##### Lamda表达å¼
å¨Java8ä¹åï¼ä½¿ç¨äº@FunctionalInterface注解æ¥ä¿®é¥°Runnableæ¥å£ï¼è¡¨æRunnableæ¥å£æ¯ä¸ä¸ªå½æ°å¼æ¥å£ï¼æä¸åªæä¸ä¸ªæ½è±¡æ¹æ³ï¼å¯ä»¥Lambdaæ¹å¼æ¥å建Runnableå¯¹è±¡ï¼æ¯ä½¿ç¨å¿åç±»çæ¹å¼æ´å ç®æ´ä¸äºã
```java
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
```
å æ¤ä¸é¢ç代ç ä¹å¯ä»¥æä»¥ä¸æ¹å¼åï¼
```java
Thread thread = new Thread(()->{
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºrunæ¹æ³");
})
thread.start()
```
##### æ»ç»
è¿ç§åæ³ä¸ç¨ç»§æ¿Threadï¼ä½æ¯åæ ·ä¹æç¼ºç¹ï¼å°±æ¯çº¿ç¨æ¹æ³ä½(ä¹å°±æ¯runæ¹æ³)ä¸è½è®¾ç½®è¿åå¼ã
#### 第ä¸ç§ å®ç°Callableæ¥å£
Runnableæ¥å£ä¸çrun()æ¹æ³æ¯æ²¡æè¿åå¼ï¼å¦ææä»¬éè¦æ§è¡çä»»å¡å¸¦è¿åå¼å°±ä¸è½ä½¿ç¨Runnableæ¥å£ãå建ä¸ä¸ªç±»CallableTargetï¼å®ç°Callableæ¥å£ï¼å®ç°å¸¦æ**è¿åå¼çcall()æ¹æ³**ï¼ç¶åæ ¹æ®CallableTargetå建ä¸ä¸ªä»»å¡FutureTaskï¼ç¶åæ ¹æ®FutureTaskæ¥å建ä¸ä¸ªçº¿ç¨Threadï¼è°ç¨Threadçstartæ¹æ³å¯ä»¥æ§è¡ä»»å¡ã
```java
public class CallableTarget implements Callable {
public Integer call() throws InterruptedException {
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºcallæ¹æ³");
Thread.sleep(5000);
return 1;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println(Thread.currentThread().getName()+"çº¿ç¨æ§è¡äºmainæ¹æ³");
CallableTarget callableTarget = new CallableTarget();
FutureTask task = new FutureTask(callableTarget);
Thread thread = new Thread(task);
thread.start();
Integer result = task.get();//å½å线ç¨ä¼é»å¡ï¼ä¸ç´çå°ç»æè¿åã
System.out.println("æ§è¡å®æ¯ï¼æå°result="+result);
System.out.println("æ§è¡å®æ¯");
}
}
```
åçå°±æ¯Threadç±»é»è®¤çrun()æ¹æ³å®ç°æ¯ä¼å»è°ç¨èªèº«å®ä¾åétargetçrun()æ¹æ³ï¼(targetå°±æ¯æä»¬æé Threadä¼ å
¥çFutureTask)ï¼èFutureTaskçrunæ¹æ³ä¸å°±ä¼è°ç¨Callableæ¥å£çå®ä¾çcall()æ¹æ³ã
```java
//Threadç±»çrunæ¹æ³å®ç°
@Override
public void run() {
if (target != null) {
//è¿étargetå°±æ¯æä»¬å¨å建Threadæ¶ä¼ å
¥çFutureTaskå®ä¾åé
target.run();
}
}
//FutureTaskç±»çrunæ¹æ³å®ç°
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
//å¨è¿éä¼è°ç¨Callableå®ä¾çcallæ¹æ³
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
```
### Javaä¸çRunnableãCallableãFutureãFutureTaskçåºå«åèç³»ï¼
æåå§çéè¿æ°å»ºçº¿ç¨æ§è¡ä»»å¡çæ¹æ³å°±æ¯æä»¬å»æ°å»ºä¸ä¸ªç±»ï¼ç»§æ¿Threadï¼ç¶åå»éårun()æ¹æ³ï¼ä½æ¯è¿æ ·éå¶å¤ªå¤§äºï¼Javaä¹ä¸æ¯æå¤ç»§æ¿ãæä»¥æäºRunnableã
##### Runnable
Runnableæ¯ä¸ä¸ªæ¥å£ï¼åªéè¦æ°å»ºä¸ä¸ªç±»å®ç°è¿ä¸ªæ¥å£ï¼ç¶åéårunæ¹æ³ï¼å°è¯¥ç±»çå®ä¾ä½ä¸ºå建Threadçå
¥åï¼çº¿ç¨è¿è¡æ¶å°±ä¼è°ç¨è¯¥å®ä¾çrunæ¹æ³ã
```java
@FunctionalInterfacepublic interface Runnable {
public abstract void run();
}
```
Thread.start()æ¹æ³->Thread.run()æ¹æ³->target.run()æ¹æ³
##### Callable
Callableè·Runnable类似ï¼ä¹æ¯ä¸ä¸ªæ¥å£ãåªä¸è¿å®çcallæ¹æ³æè¿åå¼ï¼å¯ä»¥ä¾ç¨åºæ¥æ¶ä»»å¡æ§è¡çç»æã
```java
@FunctionalInterfacepublic interface Callable {
V call() throws Exception;
}
```
##### Future
Future乿¯ä¸ä¸ªæ¥å£ï¼Future就忝ä¸ä¸ªç®¡çç容å¨ä¸æ ·ï¼è¿ä¸æ¥å¯¹RunableåCallableçå®ä¾è¿è¡å°è£
ï¼å®ä¹äºä¸äºæ¹æ³ãåæ¶ä»»å¡çcancel()æ¹æ³ï¼æ¥è¯¢ä»»å¡æ¯å¦å®æçisDone()æ¹æ³ï¼è·åæ§è¡ç»æçget()æ¹æ³ï¼å¸¦æè¶
æ¶æ¶é´æ¥è·åæ§è¡ç»æçget()æ¹æ³ã
```java
public interface Future {
//mayInterruptIfRunning代表æ¯å¦å¼ºå¶ä¸æ
//为trueï¼å¦æä»»å¡å·²ç»æ§è¡ï¼é£ä¹ä¼è°ç¨Thread.interrupt()æ¹æ³è®¾ç½®ä¸ææ è¯
//为falseï¼å¦æä»»å¡å·²ç»æ§è¡ï¼å°±åªä¼å°ä»»å¡ç¶ææ è®°ä¸ºåæ¶ï¼èä¸ä¼å»è®¾ç½®ä¸ææ è¯
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
```
##### FutureTask
å 为Futureåªæ¯ä¸ä¸ªæ¥å£ï¼å¹¶ä¸è½å®ä¾åï¼å¯ä»¥è®¤ä¸ºFutureTaskå°±æ¯Futureæ¥å£çå®ç°ç±»ï¼FutureTaskå®ç°äºRunnableFutureæ¥å£ï¼èRunnableFutureæ¥å£ç»§æ¿Runnableæ¥å£åFutureæ¥å£ã
```java
public class FutureTask implements RunnableFuture {
...
}
public interface RunnableFuture extends Runnable, Future {
void run();
}
```
##### ä½¿ç¨æ¡ä¾
ä½¿ç¨æ¶ï¼Runnableå®ç°ç±»çå®ä¾å¯ä»¥ä½ä¸ºThreadçå
¥å使ç¨ï¼èCallableåªè½ä½¿ç¨FutureTaskè¿è¡å°è£
使ç¨ã
```java
//Runnableé
åThreadè¿è¡ä½¿ç¨
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
//ä»»å¡ç代ç
}
});
//Callable使ç¨FutureTaskå°è£
åï¼é
åçº¿ç¨æ± è¿è¡ä½¿ç¨
ExecutorService pool = Executors.newSingleThreadExecutor();
FutureTask task = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
//ä»»å¡ç代ç
return null;
}
});
pool.submit(task);
//Runnable使ç¨FutureTaskå°è£
åï¼é
åçº¿ç¨æ± è¿è¡ä½¿ç¨
FutureTask task1 = new FutureTask(new Runnable() {
@Override
public void run() {
//ä»»å¡ç代ç
}
});
pool.submit(task1);
```
### Javaä¸å便åªäºåæ³ï¼
æ£ç¡®å¹¶ä¸å¯ä»¥åå°å»¶è¿å è½½çåæ³å
¶å®å°±æ¯ä¸ç§ï¼
1.使ç¨volatile修饰åéå¹¶ä¸åéæ ¡éªçåæ³æ¥å®ç°ã
2.使ç¨éæå
é¨ç±»æ¥å®ç°ï¼ç±»Aæä¸ä¸ªéæå
é¨ç±»Bï¼ç±»Bæä¸ä¸ªéæåéinstanceï¼ç±»AçgetInstance()æ¹æ³ä¼è¿åç±»Bçéæåéinstanceï¼å ä¸ºåªæè°ç¨getInstance()æ¹æ³æ¶æä¼å è½½éæå
é¨ç±»Bï¼è¿ç§åæ³ç¼ºç¹æ¯ä¸è½ä¼ åãï¼
3.ä½¿ç¨æä¸¾æ¥å®ç°
#### 第1ç§ ä¸å éï¼è£¸å¥åæ³ï¼
å¤çº¿ç¨æ§è¡æ¶ï¼å¯è½ä¼å¨instance宿åå§åä¹åï¼å
¶ä»çº¿æ§çº¿ç¨å¤æinstance为nullï¼ä»è乿§è¡ç¬¬äºæ¥ç代ç ï¼å¯¼è´åå§åè¦çã
```java
public class UnsafeLazyInitialization {
private static Instance instance;
public static Instance getInstance() {
if (instance == null) //1
instance = new Instance(); //2
}
return instance;
}
```
#### 第2ç§-å¯¹æ¹æ³å sychronizeé(ä¿ç§°çææ±æ¨¡å¼)
åå§å宿以åï¼æ¯æ¬¡è°ç¨getInstance()æ¹æ³é½éè¦è·å忥éï¼å¯¼è´ä¸å¿
è¦çå¼éã
```java
public class Singleton {
private static Singleton instance;
public synchronized static Singleton getInstance() {
if (instance == null)
instance = new Instance();
return instance;
}
}
```
#### 第3ç§-使ç¨éæåé(ä¿ç§°çé¥¿æ±æ¨¡å¼)
```
public class Singleton {
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
```
è¿ç§æ¹æ³æ¯ç¼ºç¹å¨äºä¸è½åå°å»¶æ¶å è½½ï¼å¨ç¬¬ä¸æ¬¡è°ç¨getInstance()æ¹æ³ä¹åï¼å¦æSingleton类被使ç¨å°ï¼é£ä¹å°±ä¼å¯¹instanceåéåå§åã
#### 第4ç§-使ç¨å鿣æ¥éå®
代ç å¦ä¸ï¼
```java
public class Singleton {
private static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) { //å鿣æ¥åå¨çæä¹å¨äºå¯è½ä¼æå¤ä¸ªçº¿ç¨è¿å
¥ç¬¬ä¸ä¸ªå¤æï¼ç¶åç«äºåæ¥éï¼çº¿ç¨Aå¾å°äºåæ¥éï¼å建äºä¸ä¸ªSingletonå®ä¾ï¼èµå¼ç»instanceï¼ç¶å鿾忥éï¼æ¤æ¶çº¿ç¨Bè·å¾åæ¥éï¼åä¼å建ä¸ä¸ªSingletonå®ä¾ï¼é æåå§åè¦çã
instance = new Singleton();
}
}
}
return instance;
}
}
```
instance = new Singleton();
è¿å¥ä»£ç 卿§è¡æ¶ä¼å解为ä¸ä¸ªæ¥éª¤ï¼
1.为对象åé
å
å空é´ã
2.æ§è¡åå§åç代ç ã
3.å°åé
好çå
åå°å设置ç»instanceå¼ç¨ã
使¯ç¼è¯å¨ä¼å¯¹æä»¤è¿è¡éæåºï¼åªè½ä¿è¯åçº¿ç¨æ§è¡æ¶ç»æä¸ä¼ååï¼ä¹å°±æ¯å¯è½ç¬¬3æ¥ä¼å¨ç¬¬2æ¥ä¹åæ§è¡ï¼æä¸ªçº¿ç¨Aå好æ§è¡å®ç¬¬3æ¥ï¼æ£å¨æ§è¡ç¬¬2æ¥æ¶ï¼æ¤æ¶å¦ææå
¶ä»çº¿ç¨Bè¿å
¥if (instance == null)夿ï¼ä¼åç°instanceä¸ä¸ºnullï¼ç¶åå°instanceè¿åï¼ä½æ¯å®é
ä¸instanceè¿æ²¡æå®æåå§åï¼çº¿ç¨Bä¼è®¿é®å°ä¸ä¸ªæªåå§å宿çinstance对象ãæä»¥éè¦å第5ç§è§£æ³ä¸æ ·ä½¿ç¨volatileæ¥ä¿®é¥°åéï¼é²æ¢éæåºã
#### 第5ç§ åºäº volatile çå鿣æ¥éå®çè§£å³æ¹æ¡
代ç å¦ä¸ï¼
```java
public class Singleton {
private volatile static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null)//å鿣æ¥åå¨çæä¹å¨äºå¯è½ä¼æå¤ä¸ªçº¿ç¨è¿å
¥ç¬¬ä¸ä¸ªå¤æï¼ç¶åç«äºåæ¥éï¼çº¿ç¨Aå¾å°äºåæ¥éï¼å建äºä¸ä¸ªSingletonå®ä¾ï¼èµå¼ç»instanceï¼ç¶å鿾忥éï¼æ¤æ¶çº¿ç¨Bè·å¾åæ¥éï¼åä¼å建ä¸ä¸ªSingletonå®ä¾ï¼é æåå§åè¦çã
instance = new Singleton();
}
}
return instance;
}
}
```
volatileå¯ä»¥ä¿è¯åéçå
åå¯è§æ§å鲿¢æä»¤éæã
volatile修饰çåéå¨ç¼è¯åï¼ä¼å¤åºä¸ä¸ªlockåç¼æä»¤ï¼lockåç¼æä»¤ç¸å½äºä¸ä¸ªå
åå±éï¼å
åæ
æ ï¼ï¼æä¸ä¸ªä½ç¨ï¼
* ç¡®ä¿æä»¤éæåºæ¶ï¼å
åå±éåçæä»¤ä¸ä¼æå°åé¢å»ï¼å
åå±éåçæä»¤ä¸ä¼æå°åé¢å»ã
* 强å¶å¯¹åéå¨çº¿ç¨å·¥ä½å
åä¸çä¿®æ¹æä½ç«å³åå
¥å°ç©çå
åã
* 妿æ¯åæä½ï¼ä¼å¯¼è´å
¶ä»CPUä¸å¯¹è¿ä¸ªåéçç¼å失æï¼å¼ºå¶å
¶ä»CPUä¸ç线ç¨å¨è·ååéæ¶ä»ç©çå
åä¸è·åæ´æ°åçå¼ã
æä»¥ä½¿ç¨volatile修饰åä¸ä¼åºç°ç¬¬3ç§åæ³ä¸ç±äºæä»¤éæåºå¯¼è´çé®é¢ã
#### 第6ç§ - 使ç¨éæå
é¨ç±»æ¥å®ç°
```java
class Test {
public static Signleton getInstance() {
return Signleton.instance ; // åªæè°ç¨getInstance()æ¹æ³æ¶ï¼æä¼å¼ç¨å°éæå
é¨ç±»Signletonï¼ä»èä¼è§¦åSignletonç±»çinstanceåéçåå§åï¼ä»¥æ¤å®ç°æå è½½çç®çã
}
private static class Signleton {
private static Signleton instance = new Signleton();
}
}
```
å 为JVMåºå±éè¿å éå®ç°ï¼ä¿è¯ä¸ä¸ªç±»åªä¼è¢«å è½½ä¸æ¬¡ï¼å¤ä¸ªçº¿ç¨å¨å¯¹ç±»è¿è¡åå§åæ¶ï¼åªæä¸ä¸ªçº¿ç¨ä¼è·å¾éï¼ç¶å对类è¿è¡åå§åï¼å
¶ä»çº¿ç¨ä¼é»å¡çå¾
ãæä»¥å¯ä»¥ä½¿ç¨ä¸é¢çä»£ç æ¥ä¿è¯instanceåªä¼è¢«åå§å䏿¬¡ï¼è¿ç§åæ³çé®é¢å¨äºå建å便¶ä¸è½ä¼ åã
#### 7.ä½¿ç¨æä¸¾æ¥å®ç°åä¾
```java
public enum Singleton {
//æ¯ä¸ªå
ç´ å°±æ¯ä¸ä¸ªåä¾
INSTANCE;
//èªå®ä¹çä¸äºæ¹æ³
public void method(){}
}
```
è¿ç§åæ³æ¯è¾ç®æ´ï¼ä½æ¯ä¸å¤ªä¾¿äºé
读åçè§£ï¼æä»¥å®é
å¼åä¸åºç¨å¾æ¯è¾å°ï¼èä¸ç±äºæä¸¾ç±»æ¯ä¸è½éè¿åå°æ¥å建å®ä¾ç(åå°æ¹æ³newInstanceä¸å¤ææ¯æä¸¾ç±»åï¼ä¼æåºIllegalArgumentExceptionå¼å¸¸)ï¼æä»¥å¯ä»¥é²æ¢åå°ãèä¸ç±äºæä¸¾ç±»åçååºå忝éè¿java.lang.EnumçvalueOfæ¹æ³æ¥å®ç°çï¼ä¸è½èªå®ä¹åºååæ¹æ³ï¼å¯ä»¥é²æ¢éè¿åºå忥å建å¤ä¸ªåä¾ã
### å¦ä½è§£å³åºååæ¶å¯ä»¥å建åºåä¾å¯¹è±¡çé®é¢?
妿å°åä¾å¯¹è±¡åºååæåèåºååï¼ç¶ååååºåæå¯¹è±¡ï¼é£ä¹å°±å¯ä»¥å建åºä¸ä¸ªæ°çåä¾å¯¹è±¡ï¼ä»è导è´åä¾ä¸å¯ä¸ï¼é¿å
åçè¿ç§æ
åµçè§£å³æ¹æ¡æ¯å¨åä¾ç±»ä¸å®ç°readResolve()æ¹æ³ã
```java
public class Singleton implements java.io.Serializable {
private Object readResolve() {
return INSTANCE;
}
}
```
éè¿å®ç°readResolveæ¹æ³ï¼ObjectInputStreamå®ä¾å¯¹è±¡å¨è°ç¨readObject()æ¹æ³è¿è¡ååºååæ¶ï¼å°±ä¼å¤æç¸åºçç±»æ¯å¦å®ç°äºreadResolve()æ¹æ³ï¼å¦æå®ç°äºï¼å°±ä¼è°ç¨readResolve()æ¹æ³è¿åä¸ä¸ªå¯¹è±¡ä½ä¸ºååºååçç»æï¼è䏿¯å»å建ä¸ä¸ªæ°ç对象ã
### volatileå
³é®åæä»ä¹ç¨ï¼æä¹çè§£å¯è§æ§ï¼ä¸è¬ä»ä¹åºæ¯å»ç¨å¯è§æ§ï¼
å½çº¿ç¨è¿è¡ä¸ä¸ªvolatileåéçåæä½æ¶ï¼JITç¼è¯å¨çæçæ±ç¼æä»¤ä¼å¨åæä½çæä»¤åé¢å ä¸ä¸ä¸ªâlockâæä»¤ã
Java代ç å¦ä¸:
```java
instance = new Singleton(); // instanceæ¯volatileåé
è½¬åææ±ç¼ä»£ç ï¼å¦ä¸ã
0x01a3de1d: movb $0Ã0,0Ã1104800(%esi);0x01a3de24: lock addl $0Ã0,(%esp);
```
âlockâæä¸ä¸ªä½ç¨ï¼
1.å°å½åCPUç¼åè¡çæ°æ®ä¼ååå°ç³»ç»å
åã
2.è¿ä¸ªååå
åçæä½ä¼ä½¿å¾å
¶ä»CPUéç¼åäºè¯¥å
åå°åçæ°æ®æ æã
3.ç¡®ä¿æä»¤éæåºæ¶ï¼å
åå±éåçæä»¤ä¸ä¼æå°åé¢å»ï¼å
åå±éåçæä»¤ä¸ä¼æå°åé¢å»ã
å¯è§æ§å¯ä»¥ç解为ä¸ä¸ªçº¿ç¨çåæä½å¯ä»¥ç«å³è¢«å
¶ä»çº¿ç¨å¾ç¥ãä¸ºäºæé«CPUå¤çé度ï¼CPUä¸è¬ä¸ç´æ¥ä¸å
åè¿è¡éä¿¡ï¼èæ¯å°ç³»ç»å
åçæ°æ®è¯»å°å
é¨ç¼åï¼åè¿è¡æä½ãå¯¹äºæ®éçåéï¼ä¿®æ¹å®ä¸ç¥é使¶ä¼æ´æ°å°ç³»ç»å
åã使¯å¦ææ¯å¯¹volatile修饰çåéè¿è¡åæä½ï¼JVMå°±ä¼åå¤çå¨åé䏿¡Lockåç¼çæä»¤ï¼å°è¿ä¸ªåéæå¨çç¼åè¡çæ°æ®ç«å³ååå°ç³»ç»å
åã使¯å³ä¾¿ååå°ç³»ç»å
åï¼å
¶ä»CPUä¸çç¼åè¡æ°æ®è¿æ¯æ§çï¼ä¸ºäºä¿è¯æ°æ®ä¸è´æ§ï¼å
¶ä»CPUä¼å
æ¢å¨æ»çº¿ä¸ä¼ æçæ°æ®æ¥æ£æ¥èªå·±çç¼åè¡ç弿¯å¦è¿æï¼å½CPUåç°ç¼åè¡å¯¹åºçå
åå°å被修æ¹ï¼é£ä¹å°±ä¼å°å½åç¼åè¡è®¾ç½®ä¸ºæ æï¼ä¸æ¬¡å½CPU对è¿ä¸ªç¼åè¡ä¸çæ°æ®è¿è¡ä¿®æ¹æ¶ï¼ä¼éæ°ä»ç³»ç»å
åä¸ææ°æ®è¯»å°å¤çå¨ç¼åéã
##### 使ç¨åºæ¯
##### 读åé
妿éè¦å®ç°ä¸ä¸ªè¯»åéï¼æ¯æ¬¡åªè½ä¸ä¸ªçº¿ç¨å»åæ°æ®ï¼ä½æ¯æå¤ä¸ªçº¿ç¨æ¥è¯»æ°æ®ï¼å°±synchronized忥鿥坹setæ¹æ³å éï¼getæ¹æ³ä¸å éï¼ ä½¿ç¨volatileæ¥ä¿®é¥°åéï¼ä¿è¯å
åå¯è§æ§ï¼ä¸ç¶å¤ä¸ªçº¿ç¨å¯è½ä¼å¨åéä¿®æ¹åè¿è¯»å°ä¸ä¸ªæ§å¼ã
```java
volatile Integer a;
//å¯ä»¥å®ç°ä¸åå¤è¯»çåºæ¯ï¼ä¿è¯å¹¶åä¿®æ¹æ°æ®æ¶çæ£ç¡®ã
set(Integer c) {
synchronized(this.a) {
this.a = c;
}
}
get() {
return a;
}
```
##### ç¶æä½
ç¨äºåç¶æä½æ å¿ï¼å¦æå¤ä¸ªçº¿ç¨å»éè¦æ ¹æ®ä¸ä¸ªç¶æä½æ¥æ§è¡ä¸äºæä½ï¼ä½¿ç¨volatile修饰å¯ä»¥ä¿è¯å
åå¯è§æ§ã
ç¨äºå便¨¡å¼ç¨äºä¿è¯å
åå¯è§æ§ï¼ä»¥å鲿¢æä»¤éæåºã
### Javaä¸çº¿ç¨çç¶ææ¯æä¹æ ·çï¼
卿ä½ç³»ç»ä¸ï¼çº¿ç¨çåäºè½»é级çè¿ç¨ã

æä»¥ä¼ ç»çæä½ç³»ç»çº¿ç¨ä¸è¬æä»¥ä¸ç¶æ
1. **æ°å»ºç¶æ**:
ä½¿ç¨ new å
³é®åå Thread ç±»æå
¶å类建ç«ä¸ä¸ªçº¿ç¨å¯¹è±¡åï¼è¯¥çº¿ç¨å¯¹è±¡å°±å¤äºæ°å»ºç¶æãå®ä¿æè¿ä¸ªç¶æç´å°ç¨åº start() è¿ä¸ªçº¿ç¨ã
2. **å°±ç»ªç¶æ**:
å½çº¿ç¨å¯¹è±¡è°ç¨äºstart()æ¹æ³ä¹åï¼è¯¥çº¿ç¨å°±è¿å
¥å°±ç»ªç¶æãå°±ç»ªç¶æç线ç¨å¤äºå°±ç»ªéåä¸ï¼è¦çå¾
JVMé线ç¨è°åº¦å¨çè°åº¦ã
3. **è¿è¡ç¶æ:**
å¦æå°±ç»ªç¶æç线ç¨è·å CPU èµæºï¼å°±å¯ä»¥æ§è¡ run()ï¼æ¤æ¶çº¿ç¨ä¾¿å¤äºè¿è¡ç¶æãå¤äºè¿è¡ç¶æççº¿ç¨æä¸ºå¤æï¼å®å¯ä»¥å为é»å¡ç¶æãå°±ç»ªç¶æåæ»äº¡ç¶æã
4. **é»å¡ç¶æ:**
妿ä¸ä¸ªçº¿ç¨æ§è¡äºsleepï¼ç¡ç ï¼ãsuspendï¼æèµ·ï¼çæ¹æ³ï¼å¤±å»æå ç¨èµæºä¹åï¼è¯¥çº¿ç¨å°±ä»è¿è¡ç¶æè¿å
¥é»å¡ç¶æãå¨ç¡ç æ¶é´å·²å°æè·å¾è®¾å¤èµæºåå¯ä»¥éæ°è¿å
¥å°±ç»ªç¶æãå¯ä»¥å为ä¸ç§ï¼
- çå¾
é»å¡ï¼è¿è¡ç¶æä¸ççº¿ç¨æ§è¡ wait() æ¹æ³ï¼ä½¿çº¿ç¨è¿å
¥å°çå¾
é»å¡ç¶æã
- 忥é»å¡ï¼çº¿ç¨å¨è·å synchronized忥é失败(å ä¸ºåæ¥é被å
¶ä»çº¿ç¨å ç¨)ã
- å
¶ä»é»å¡ï¼éè¿è°ç¨çº¿ç¨ç sleep() æ join() ååºäº I/Oè¯·æ±æ¶ï¼çº¿ç¨å°±ä¼è¿å
¥å°é»å¡ç¶æãå½sleep() ç¶æè¶
æ¶ï¼join() çå¾
线ç¨ç»æ¢æè¶
æ¶ï¼æè
I/O å¤ç宿¯ï¼çº¿ç¨éæ°è½¬å
¥å°±ç»ªç¶æã
5. **æ»äº¡ç¶æ:**
ä¸ä¸ªè¿è¡ç¶æç线ç¨å®æä»»å¡æè
å
¶ä»ç»æ¢æ¡ä»¶åçæ¶ï¼è¯¥çº¿ç¨å°±åæ¢å°ç»æ¢ç¶æã
使¯Javaä¸Thread对象çç¶æååè·ä¼ ç»çæä½ç³»ç»çº¿ç¨ç¶ææä¸äºåºå«ã
```java
public enum State {
NEW,//æ°å»ºæ
RUNNABLE,//è¿è¡æ
BLOCKED,//é»å¡æ
WAITING,//çå¾
æ
TIMED_WAITING,//ææ¶é´éå¶ççå¾
æ
TERMINATED;//æ»äº¡æ
}
```

#### NEW æ°å»ºæ
å¤äºNEWç¶æççº¿ç¨æ¤æ¶å°æªå¯å¨ï¼è¿æ²¡è°ç¨Threadå®ä¾çstart()æ¹æ³ã
#### RUNNABLE è¿è¡æ
表示å½åçº¿ç¨æ£å¨è¿è¡ä¸ãå¤äºRUNNABLEç¶æç线ç¨å¯è½å¨Javaèææºä¸è¿è¡ï¼ä¹æå¯è½å¨çå¾
å
¶ä»ç³»ç»èµæºï¼æ¯å¦I/Oï¼ã
> Java线ç¨ç**RUNNABLE**ç¶æå
¶å®æ¯å
æ¬äºä¼ ç»æä½ç³»ç»çº¿ç¨ç**ready**å**running**ä¸¤ä¸ªç¶æçã
#### BLOCKED é»å¡æ
é»å¡ç¶æãçº¿ç¨æ²¡æç³è¯·å°synchronize忥éï¼å°±ä¼å¤äºé»å¡ç¶æï¼çå¾
éç鿾以è¿å
¥åæ¥åºã
#### WAITING çå¾
æ
çå¾
ç¶æãå¤äºçå¾
ç¶æç线ç¨åæRUNNABLEç¶æéè¦å
¶ä»çº¿ç¨å¤éã
è°ç¨å¦ä¸3ä¸ªæ¹æ³ä¼ä½¿çº¿ç¨è¿å
¥çå¾
ç¶æï¼
- Object.wait()ï¼ä½¿å½å线ç¨å¤äºçå¾
ç¶æç´å°å¦ä¸ä¸ªçº¿ç¨è°ç¨notifyå¤éå®ï¼
- Thread.join()ï¼çå¾
çº¿ç¨æ§è¡å®æ¯ï¼åºå±è°ç¨çæ¯Objectå®ä¾çwait()æ¹æ³ï¼
- LockSupport.park()ï¼é¤éè·å¾è°ç¨è®¸å¯ï¼å¦åç¦ç¨å½å线ç¨è¿è¡çº¿ç¨è°åº¦ã
#### TIMED_WAITING è¶
æ¶çå¾
ç¶æ
è¶
æ¶çå¾
ç¶æã线ç¨çå¾
ä¸ä¸ªå
·ä½çæ¶é´ï¼æ¶é´å°åä¼è¢«èªå¨å¤éã
è°ç¨å¦ä¸æ¹æ³ä¼ä½¿çº¿ç¨è¿å
¥è¶
æ¶çå¾
ç¶æï¼
- Thread.sleep(long millis)ï¼ä½¿å½å线ç¨ç¡ç æå®æ¶é´ï¼
- Object.wait(long timeout)ï¼çº¿ç¨ä¼ç æå®æ¶é´ï¼çå¾
æé´å¯ä»¥éè¿notify()/notifyAll()å¤éï¼
- Thread.join(long millis)ï¼çå¾
å½åçº¿ç¨æå¤æ§è¡millis毫ç§ï¼å¦æmillis为0ï¼åä¼ä¸ç´æ§è¡ï¼
- LockSupport.parkNanos(long nanos)ï¼ é¤éè·å¾è°ç¨è®¸å¯ï¼å¦åç¦ç¨å½å线ç¨è¿è¡çº¿ç¨è°åº¦æå®æ¶é´ï¼
- LockSupport.parkUntil(long deadline)ï¼åä¸ï¼ä¹æ¯ç¦æ¢çº¿ç¨è¿è¡è°åº¦æå®æ¶é´ï¼
#### TERMINATED ç»æ¢æ
ç»æ¢ç¶æãæ¤æ¶çº¿ç¨å·²æ§è¡å®æ¯ã
#### ç¶æè½¬æ¢
1.BLOCKEDä¸RUNNABLEç¶æç转æ¢
å¤äºBLOCKEDç¶æççº¿ç¨æ¯å 为å¨çå¾
éçéæ¾ï¼å½è·å¾éä¹å就转æ¢ä¸ºRUNNABLEç¶æã
2.WAITINGç¶æä¸RUNNABLEç¶æç转æ¢
**Object.wait()**ï¼**Thread.join()**å**LockSupport.park()**è¿3ä¸ªæ¹æ³å¯ä»¥ä½¿çº¿ç¨ä»RUNNABLEç¶æè½¬ä¸ºWAITINGç¶æã
3.TIMED_WAITINGä¸RUNNABLEç¶æè½¬æ¢
TIMED_WAITINGä¸WAITINGç¶æç±»ä¼¼ï¼åªæ¯TIMED_WAITINGç¶æçå¾
çæ¶é´æ¯æå®çã
è°ç¨**Thread.sleep(long)**ï¼**Object.wait(long)**ï¼**Thread.join(long)**ä¼ä½¿å¾RUNNABLEç¶æè½¬æ¢ä¸ºTIMED_WAITINGç¶æ
### wait()ï¼join()ï¼sleep()æ¹æ³æä»ä¹ä½ç¨ï¼
é¦å
éè¦å¯¹wait()ï¼join()ï¼sleep()æ¹æ³è¿è¡ä»ç»ã
#### Object.wait()æ¹æ³æ¯ä»ä¹ï¼
è°ç¨wait()æ¹æ³å线ç¨å¿
é¡»ææå¯¹è±¡Objectçéã线ç¨è°ç¨wait()æ¹æ³åï¼ä¼éæ¾å½åçObjectéï¼è¿å
¥éçmonitor对象ççå¾
éåï¼ç´å°æå
¶ä»çº¿ç¨è°ç¨notify()/notifyAll()æ¹æ³å¤éçå¾
éç线ç¨ã
éè¦æ³¨æçæ¯ï¼å
¶ä»çº¿ç¨è°ç¨notify()æ¹æ³åªä¼å¤éå个çå¾
éç线ç¨ï¼å¦ææå¤ä¸ªçº¿ç¨é½å¨çå¾
è¿ä¸ªéçè¯ï¼ä¸ä¸å®ä¼å¤éå°ä¹åè°ç¨wait()æ¹æ³ç线ç¨ã
åæ ·ï¼è°ç¨notifyAll()æ¹æ³å¤éææçå¾
éç线ç¨ä¹åï¼ä¹ä¸ä¸å®ä¼é©¬ä¸ææ¶é´çåç»åææ¾å¼éçé£ä¸ªçº¿ç¨ï¼å
·ä½è¦çç³»ç»çè°åº¦ã
#### Thread.join()æ¹æ³æ¯ä»ä¹ï¼
join()æ¹æ³æ¯Threadç±»çä¸ä¸ªå®ä¾æ¹æ³ãå®çä½ç¨æ¯è®©å½å线ç¨é·å
¥âçå¾
âç¶æï¼çjoinçè¿ä¸ªçº¿ç¨threadAæ§è¡å®æåï¼åç»§ç»æ§è¡å½å线ç¨ã
å®ç°åçæ¯join()æ¹æ³æ¬èº«æ¯ä¸ä¸ªsychronizedä¿®é¥°çæ¹æ³ï¼ä¹å°±æ¯è°ç¨join()è¿ä¸ªæ¹æ³éè¦å
è·åthreadAçéï¼è·å¾éä¹ååè°ç¨wait()æ¹æ³æ¥è¿è¡çå¾
ï¼ä¸ç´å°threadAæ§è¡å®æåï¼threadAä¼è°ç¨notify_all()æ¹æ³,å¤éææçå¾
ç线ç¨ï¼å½åçº¿ç¨æä¼ç»æçå¾
ã
```java
Thread threadA = new Thread();
threadA.join();
```
join()æ¹æ³çæºç ï¼
```java
public final void join() throws InterruptedException {
join(0);//0çè¯ä»£è¡¨æ²¡æè¶
æ¶æ¶é´ä¸ç´çä¸å»
}
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
```
è¿æ¯jvmä¸Theadçæºç ï¼å¨çº¿ç¨æ§è¡ç»æåä¼è°ç¨notify_allæ¥å¤éçå¾
ç线ç¨ã
```java
//ä¸ä¸ªc++彿°ï¼
void JavaThread::exit(bool destroy_vm, ExitType exit_type) ï¼
//é颿ä¸ä¸ªè´¼ä¸èµ·ç¼çä¸è¡ä»£ç
ensure_join(this);
static void ensure_join(JavaThread* thread) {
Handle threadObj(thread, thread->threadObj());
ObjectLocker lock(threadObj, thread);
thread->clear_pending_exception();
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
java_lang_Thread::set_thread(threadObj(), NULL);
//åå¿ä»¬çå°äºæ²¡ï¼å«çä¸ç¨çï¼å°±çè¿ä¸å¥
//threadå°±æ¯å½å线ç¨ï¼æ¯å¥ï¼å°±æ¯åæä¾åä¸è¯´çthreadA线ç¨
lock.notify_all(thread);
thread->clear_pending_exception();
}
```
#### sleep()æ¹æ³æ¯ä»ä¹ï¼
sleepæ¹æ³æ¯Threadç±»çä¸ä¸ªéææ¹æ³ãå®çä½ç¨æ¯è®©å½å线ç¨ç¡ç 䏿®µæ¶é´ãï¼**sleepæ¹æ³æ¯ä¸ä¼éæ¾å½åçº¿ç¨ææçéï¼èwaitæ¹æ³ä¼ã**
sleepä¸waitæ¹æ³çåºå«ï¼
- waitå¯ä»¥æå®æ¶é´ï¼ä¹å¯ä»¥ä¸æå®ï¼èsleepå¿
é¡»æå®æ¶é´ã
- waitéæ¾cpuèµæºï¼åæ¶éæ¾éï¼sleepéæ¾cpuèµæºï¼ä½æ¯ä¸éæ¾éï¼æä»¥ææ»éãï¼è°ç¨join()æ¹æ³ä¹ä¸ä¼éæ¾éï¼
- waitå¿
é¡»æ¾å¨åæ¥åæåæ¥æ¹æ³ä¸ï¼èsleepå¯ä»¥åä»»æä½ç½®ã
åèæç« ï¼
http://redspider.group:4000/article/01/4.html
https://www.jianshu.com/p/5d88b122a050
### Thread.sleep(),Object.wait(),LockSupport.park()æä»ä¹åºå«ï¼
1.è¿ä¸ä¸ªæ¹æ³é½ä¼è®©çº¿ç¨æèµ·ï¼éæ¾CPUæ¶é´çï¼è¿å
¥å°é»å¡æã使¯Object.wait()éè¦éæ¾éï¼æä»¥å¿
é¡»å¨synchronized忥éä¸ä½¿ç¨ï¼åçé
å¥çObject.notify()乿¯ãèThead.sleep(),LockSupport.park()ä¸éè¦å¨synchronized忥éä¸ä½¿ç¨ï¼å¹¶ä¸å¨è°ç¨æ¶ä¹ä¸ä¼éæ¾éã
2.ç±äºThread.sleep()没æå¯¹åºçå¤é线ç¨çæ¹æ³ï¼æä»¥å¿
é¡»æå®è¶
æ¶æ¶é´ï¼è¶
è¿æ¶é´åï¼çº¿ç¨æ¢å¤ãæä»¥è°ç¨Thread.sleep()åç线ç¨ä¸è¬æ¯åºäºTIME_WAITINGç¶æï¼èè°ç¨äºObject.wait()ï¼LockSupport.park()çæ¹æ³æ¯è¿å
¥å°WAITINGç¶æã
3.Object.wait()对åºçå¤éæ¹æ³ä¸ºObject.notify()ï¼LockSupport.park()对åºçå¤éæ¹æ³ä¸ºLockSupport.unpark()ã
4.å¨ä»£ç ä¸å¿
é¡»è½ä¿è¯waitæ¹æ³æ¯notifyæ¹æ³å
æ§è¡ï¼å¦ænotifyæ¹æ³æ¯waitæ¹æ³æ©æ§è¡çè¯ï¼å°±ä¼å¯¼è´å waitæ¹æ³è¿å
¥ä¼ç ççº¿ç¨æ¥æ¶ä¸å°å¤ééç¥çé®é¢ãèparkãunparkåä¸ä¼æè¿ä¸ªé®é¢ï¼æä»¬å¯ä»¥å
è°ç¨unparkæ¹æ³éæ¾ä¸ä¸ªè®¸å¯è¯ï¼è¿æ ·åé¢çº¿ç¨è°ç¨parkæ¹æ³æ¶ï¼åç°å·²ç»è®¸å¯è¯äºï¼å°±å¯ä»¥ç´æ¥è·å许å¯è¯èä¸ç¨è¿å
¥ä¼ç ç¶æäºãï¼**LockSupport.park() çå®ç°åçæ¯éè¿äºå
ä¿¡å·éåçé»å¡ï¼è¦æ³¨æçæ¯ï¼è¿ä¸ªä¿¡å·éæå¤åªè½å å°1ï¼ä¹å°±æ¯æ 论æ§è¡å¤å°æ¬¡unpark()æ¹æ³ï¼ä¹æå¤åªä¼æä¸ä¸ªè®¸å¯è¯ã**ï¼
5.ä¸ç§æ¹æ³è®©çº¿ç¨è¿å
¥é»å¡æåï¼é½å¯ä»¥ååºä¸æï¼ä¹å°±æ¯è°ç¨Thread.interrupt()æ¹æ³ä¼è®¾ç½®ä¸ææ å¿ä½ï¼ä¹åæ§è¡Thread.sleep(),Object.wait()äºç线ç¨ä¼æåºInterruptedExceptionå¼å¸¸ï¼ç¶åéè¦ä»£ç è¿è¡å¤çãèè°ç¨äºpark()æ¹æ³ç线ç¨å¨ååºä¸æåªä¼ç¸å½äºä¸æ¬¡æ£å¸¸çå¤éæä½ï¼çä»·äºè°ç¨unpark()æ¹æ³ï¼ï¼è®©çº¿ç¨å¤éï¼ç»§ç»æ§è¡åé¢ç代ç ï¼ä¸ä¼æåºInterruptedExceptionå¼å¸¸ã

åè龿¥ï¼
https://blog.csdn.net/u013332124/article/details/84647915
### è°ä¸è°ä½ 对线ç¨ä¸æççè§£ï¼
å¨Javaä¸è®¤ä¸ºï¼ä¸ä¸ªçº¿ç¨ä¸åºè¯¥ç±å
¶ä»çº¿ç¨æ¥å¼ºå¶ä¸ææè
åæ¢ï¼æä»¥ä¸äºä¼å¼ºå¶ä¸æçº¿ç¨çæ¹æ³Thread.stop(), Thread.suspend()æ¹æ³é½å·²ç»åºå¼äºãæä»¥ä¸è¬æ¯éè¿è°ç¨thread.interrupt();æ¹æ³æ¥è®¾ç½®çº¿ç¨ç䏿æ è¯ï¼
1.è¿æ ·å¦æçº¿ç¨æ¯å¤äºé»å¡ç¶æï¼ä¼æåºInterruptedExceptionå¼å¸¸ï¼ä»£ç å¯ä»¥è¿è¡æè·ï¼è¿è¡ä¸äºå¤çãï¼ä¾å¦Object#waitãThread#sleepãBlockingQueue#putãBlockingQueue#takeãå
¶ä¸BlockingQueue主è¦è°ç¨conditon.await()æ¹æ³è¿è¡çå¾
ï¼åºå±éè¿LockSupport.park()å®ç°ï¼
2.å¦æçº¿ç¨æ¯å¤äºRUNNABLEç¶æï¼ä¹å°±æ¯æ£å¸¸è¿è¡ï¼è°ç¨thread.interrupt();åªæ¯ä¼è®¾ç½®ä¸ææ å¿ä½ï¼ä¸ä¼æä»ä¹å
¶ä»æä½ã
```java
//å°çº¿ç¨ç䏿æ è¯è®¾ç½®ä¸ºtrue
thread.interrupt();
//å¤æçº¿ç¨ç䏿æ è¯æ¯å¦ä¸ºtrue
thread.isInterrupted()
//ä¼è¿åå½åç线ç¨ä¸æç¶æï¼å¹¶ä¸é置线ç¨ç䏿æ è¯ï¼å°ä¸ææ è¯è®¾ç½®ä¸ºfalse
thread.interrupted()
```
### çº¿ç¨æ§è¡çä»»å¡å¯ä»¥ç»æ¢åï¼
##### 1.è®¾ç½®ä¸æ
FutureTaskæä¾äºcancel(boolean mayInterruptIfRunning)æ¹æ³æ¥åæ¶ä»»å¡ï¼å¹¶ä¸
妿å
¥å为falseï¼å¦æä»»å¡å·²ç»å¨æ§è¡ï¼é£ä¹ä»»å¡å°±ä¸ä¼è¢«åæ¶ã
妿å
¥å为trueï¼å¦æä»»å¡å·²ç»å¨æ§è¡ï¼é£ä¹ä¼è°ç¨Threadçinterrupt()æ¹æ³æ¥è®¾ç½®çº¿ç¨ç䏿æ è¯ï¼å¦æçº¿ç¨å¤äºé»å¡ç¶æï¼ä¼æåºInterruptedExceptionå¼å¸¸ï¼å¦ææ£å¸¸ç¶æåªæ¯è®¾ç½®æ å¿ä½ï¼ä¿®æ¹interruptedåéçå¼ãæä»¥å¦æè¦åæ¶ä»»å¡åªè½å¨ä»»å¡å
é¨ä¸è°ç¨thread.isInterrupted()æ¹æ³è·åå½å线ç¨çä¸æç¶æï¼èªè¡åæ¶ã
##### 2.线ç¨çstopæ¹æ³
线ç¨çstop()æ¹æ³å¯ä»¥è®©çº¿ç¨åæ¢æ§è¡ï¼éæ¾ææçéï¼æåºThreadDeathè¿ç§Errorã使¯å¨éæ¾éä¹åï¼æ²¡æåæ³è®©åè¿äºéä¿æ¤çèµæºï¼å¯¹è±¡å¤äºä¸ä¸ªå®å
¨ï¼ä¸è´çç¶æãï¼ä¾å¦æä¸ä¸ªåéaï¼æ¬æ¥ç弿¯0ï¼ä½ ç线ç¨ä»»å¡æ¯å°a++åç¶ååè¿è¡a--ãæ£å¸¸æ
åµä¸ä»»å¡æ§è¡å®ä¹åï¼å
¶ä»çº¿ç¨åå°è¿ä¸ªåéaçå¼åºè¯¥æ¯0ï¼ä½æ¯å¦æä¹åè°ç¨äºThread.stopæ¹æ³æ¶ï¼æ£å¥½æ¯å¨a++ä¹åï¼é£ä¹åéa就伿¯1ï¼è¿æ ·å
¶ä»çº¿ç¨åå°çaå°±æ¯åºäºä¸ä¸è´çç¶æãï¼
### 让线ç¨é¡ºåºæ§è¡æåªäºæ¹æ³ï¼
##### 1.主线ç¨Join
å°±æ¯è°ç¨threadA.start()æ¹æ³è®©çº¿ç¨Aå
æ§è¡ï¼ç¶å主线ç¨è°ç¨threadA.join()æ¹æ³ï¼ç¶å主线ç¨è¿å
¥TIME_WAITINGç¶æï¼ç´å°threadAæ§è¡ç»æåï¼ä¸»çº¿ç¨æè½ç»§ç»å¾ä¸æ§è¡ï¼æ§è¡çº¿ç¨Bçä»»å¡ã(joinæ¹æ³çåºå±å®ç°å
¶å®æ¯è°ç¨äºthreadAçwait()æ¹æ³ï¼å½çº¿ç¨Aæ§è¡å®æ¯åï¼ä¼èªå¨è°ç¨notifyAll()æ¹æ³å¤éææçº¿ç¨ã)
示ä¾ä»£ç å¦ä¸ï¼
```java
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
//æ§è¡threadAçä»»å¡
}
});
Thread threadB= new Thread(new Runnable() {
@Override
public void run() {
//æ§è¡threadBçä»»å¡
}
});
//æ§è¡çº¿ç¨Aä»»å¡
threadA.start();
//主线ç¨è¿è¡çå¾
threadA.join();
//æ§è¡çº¿ç¨Bçä»»å¡
threadB.start();
```
##### å线ç¨Join
å°±æ¯è®©çº¿ç¨Bçä»»å¡å¨æ§è¡æ¶ï¼è°ç¨threadA.join()æ¹æ³ï¼è¿æ ·å°±åªæç线ç¨Aç任塿§è¡å®æåï¼æä¼æ§è¡çº¿ç¨Bã
```java
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
//æ§è¡threadAçä»»å¡
}
});
Thread threadB= new Thread(new Runnable() {
@Override
public void run() {
//å线ç¨è¿è¡çå¾
ï¼ç¥éthreadA任塿§è¡å®æ¯
threadA.join();
//æ§è¡threadBçä»»å¡
}
});
//æ§è¡çº¿ç¨Aä»»å¡
threadA.start();
//æ§è¡çº¿ç¨Bçä»»å¡
threadB.start();
```
##### åçº¿ç¨æ± æ³
å°±æ¯ä½¿ç¨Executors.newSingleThreadExecutor()è¿ä¸ªçº¿ç¨æ± ï¼è¿ä¸ªçº¿ç¨æ± çç¹ç¹å°±æ¯åªæä¸ä¸ªæ§è¡çº¿ç¨ï¼å¯ä»¥ä¿è¯ä»»å¡æé¡ºåºæ§è¡ã
```java
ExecutorService pool = Executors.newSingleThreadExecutor();
//æäº¤ä»»å¡A
executorService.submit(taskA);
//æäº¤ä»»å¡B
executorService.submit(taskB);
```
##### çå¾
éç¥æ³(waitånotify)
å°±æ¯å¨çº¿ç¨Bä¸è°ç¨Object.waiting()æ¹æ³è¿è¡çå¾
ï¼çº¿ç¨Aæ§è¡å®æ¯åè°ç¨Object.notify()æ¹æ³è¿è¡å¤éã(è¿ç§æ¹æ³æä¸¤ä¸ªç¼ºç¹ï¼ä¸ä¸ªæ¯Object.waiting()ånotify()æ¹æ³å¿
é¡»å¨åæ¥ä»£ç åä¸è°ç¨ï¼ç¬¬äºä¸ªæ¯å¦æçº¿ç¨Aæ§è¡è¿å¿«ï¼å
è°ç¨äºobject.notify()æ¹æ³ï¼å°±ä¼å¯¼è´çº¿ç¨Båé¢ä¸ç´å¾ä¸å°å¤éã)
```java
final Object object = new Object();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
//æ§è¡threadAçä»»å¡
synchronized(object) {
object.notify();
}
}
});
Thread threadB= new Thread(new Runnable() {
@Override
public void run() {
synchronized(object) {
//å线ç¨è¿è¡çå¾
ï¼ç¥éthreadA任塿§è¡å®æ¯
object.wait();
//æ§è¡threadBçä»»å¡
}
}
});
```
##### çå¾
éç¥æ³(awaitåsingal)
å
·ä½å®ç°å°±æ¯Reentrantlockå¯ä»¥å建åºä¸ä¸ªConditionå®ä¾queueï¼å¯ä»¥è®¤ä¸ºæ¯ä¸ä¸ªçå¾
éåï¼çº¿ç¨Bè°ç¨queue.await()å°±ä¼è¿è¡çå¾
ï¼ç´å°çº¿ç¨Aæ§è¡å®æ¯è°ç¨queue.signal()æ¥å¤é线ç¨Bã
```java
final ReentrantLock lock = new ReentrantLock();
final Condition queue1 = lock.newCondition();
final Object object = new Object();
final Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
//æ§è¡threadAçä»»å¡
lock.lock();
try {
//å¤é线ç¨Bçä»»å¡
queue1.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("æ§è¡äºä»»å¡A2");
lock.unlock();
}
});
final Thread threadB= new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
//å线ç¨è¿è¡çå¾
ï¼ç¥éthreadA任塿§è¡å®æ¯
try {
queue1.await();
System.out.println("æ§è¡äºä»»å¡B2");
} catch (InterruptedException e) {
e.printStackTrace();
}
//æ§è¡threadBçä»»å¡
lock.unlock();
}
});
threadA.start();
threadB.start();
```
åè龿¥ï¼
http://cnblogs.com/wenjunwei/p/10573289.html
### 线ç¨é´æä¹éä¿¡ï¼
#### 1.synchronizedé
éè¿synchronized鿥è¿è¡åæ¥ï¼è®©ä¸æ¬¡åªè½ä¸ä¸ªçº¿ç¨æ¥æ§è¡ã
#### 2.çå¾
/éç¥æºå¶
```java
//å设æä»¬çéæ±æ¯Bæ§è¡ç»æåAæè½æ§è¡
//线ç¨Aç代ç
synchronized(对象) { while(æ¡ä»¶ä¸æ»¡è¶³) {
while(æ¡ä»¶ä¸æ»¡è¶³) {
对象.wait(); //线ç¨Aè¿è¡çå¾
}
//线ç¨Aæ§è¡ç¸å
³ççé»è¾
}
//线ç¨Bç代ç
synchronized(对象) {
//线ç¨Bæ§è¡ç¸å
³ççé»è¾
//线ç¨Bå¤é线ç¨A
对象.notifyAll();
}
```
çå¾
/éç¥æºå¶ï¼æ¯æä¸ä¸ªçº¿ç¨Aè°ç¨äºå¯¹è±¡objectAçwait()æ¹æ³è¿å
¥çå¾
ç¶æï¼èå¦ä¸ä¸ªçº¿ç¨Bè°ç¨äºå¯¹è±¡objectAçnotify()æè
notifyAll()æ¹æ³ï¼çº¿ç¨Aæ¶å°éç¥åä»å¯¹è±¡objectAçwait()æ¹æ³è¿åï¼è¿èæ§è¡åç»æä½ãä¸è¿°ä¸¤ä¸ªçº¿ç¨éè¿å¯¹è±¡objectAæ¥å®æäº¤äºï¼è对象ä¸çwait()ånotify/notifyAll()çå
³ç³»å°±å¦åå¼å
³ä¿¡å·ä¸æ ·ï¼ç¨æ¥å®æçå¾
æ¹åéç¥æ¹ä¹é´ç交äºå·¥ä½ã

1)使ç¨wait()ãnotify()ånotifyAll()æ¶éè¦å
对è°ç¨å¯¹è±¡å éã
2)è°ç¨wait()æ¹æ³åï¼çº¿ç¨ç¶æç±RUNNINGå为WAITINGï¼å¹¶å°å½åçº¿ç¨æ¾ç½®å°å¯¹è±¡ç
çå¾
éåã
3)notify()ænotifyAll()æ¹æ³è°ç¨åï¼çå¾
线ç¨ä¾æ§ä¸ä¼ä»wait()è¿åï¼å 为çå¾
线ç¨åªæ¯ä»çå¾
éåå°äºåæ¥éåï¼éè¦è°ç¨notify()æ notifAll()ç线ç¨éæ¾éä¹åï¼çå¾
线ç¨è·å¾éï¼æè½ä»åæ¥éåä¸ç§»é¤ï¼æææºä¼ä»wait()è¿åï¼æè½ç»§ç»å¾ä¸æ§è¡ã
4)notify()æ¹æ³å°çå¾
éåä¸çä¸ä¸ªçå¾
线ç¨ä»çå¾
éåä¸ç§»å°åæ¥éåä¸ï¼ènotifyAll() æ¹æ³åæ¯å°çå¾
éå䏿æç线ç¨å
¨é¨ç§»å°åæ¥éåï¼è¢«ç§»å¨ç线ç¨ç¶æç±WAITINGå为 BLOCKEDã
5)ä»wait()æ¹æ³è¿åçåææ¯è·å¾äºè°ç¨å¯¹è±¡çéã

##### 3.管é
管éè¾å
¥/è¾åºæµ 管éè¾å
¥/è¾åºæµåæ®éçæä»¶è¾å
¥/è¾åºæµæè
ç½ç»è¾å
¥/è¾åºæµä¸åä¹å¤å¨äºï¼å®ä¸»è¦ ç¨äºçº¿ç¨ä¹é´çæ°æ®ä¼ è¾ï¼èä¼ è¾çåªä»ä¸ºå
åã 管éè¾å
¥/è¾åºæµä¸»è¦å
æ¬äºå¦ä¸4ç§å
·ä½å®ç°:PipedOutputStreamãPipedInputStreamã PipedReaderåPipedWriterï¼å两ç§é¢ååèï¼èå两ç§é¢åå符ã
PipedReaderåPipedWriterå¯ä»¥ä¸ä¸ªçº¿ç¨Aè°ç¨PipedWriterå®ä¾çwrite()æ¹æ³ï¼å¾éé¢åæ°æ®ï¼ç¶åä¸PipedWriterå®ä¾å»ºç«è¿æ¥çPipedReaderå®ä¾å¯ä»¥è¯»å°æ°æ®ï¼çº¿ç¨Bå¯ä»¥éè¿PipedReaderå®ä¾è¯»å°æ°æ®ã
å¨ä»£ç æ¸
å4-12æç¤ºçä¾åä¸ï¼å建äºprintThreadï¼å®ç¨æ¥æ¥åmain线ç¨çè¾å
¥ï¼ä»»ä½ main线ç¨çè¾å
¥åéè¿PipedWriteråå
¥ï¼èprintThreadå¨å¦ä¸ç«¯éè¿PipedReaderå°å
容读åºå¹¶æå°ã
ä»£ç æ¸
å4-12 Piped.java
```java
public class Piped {
public static void main(String[] args) throws Exception {
PipedWriter out = new PipedWriter();
PipedReader in = new PipedReader();
// å°è¾åºæµåè¾å
¥æµè¿è¡è¿æ¥ï¼å¦åå¨ä½¿ç¨æ¶ä¼æåºIOException out.connect(in);
Thread printThread = new Thread(new Print(in), "PrintThread"); printThread.start();
int receive = 0;
try {
while ((receive = System.in.read()) != -1) { out.write(receive);
}
} finally { out.close(); }
}
static class Print implements Runnable {
private PipedReader in;
public Print(PipedReader in) {
this.in = in;
}
public void run() {
int receive = 0;
try {
while ((receive = in.read()) != -1) { System.out.print((char) receive);
}
} catch (IOException ex) {
}
}
}
}
```
è¿è¡è¯¥ç¤ºä¾ï¼è¾å
¥ä¸ç»å符串ï¼å¯ä»¥çå°è¢«printThreadè¿è¡äºåæ ·è¾åºã
Repeat my words.
Repeat my words.
#### 4.Thread.join
Thread.join()ç使ç¨å¦æä¸ä¸ªçº¿ç¨Aæ§è¡äºthread.join()è¯å¥ï¼å½å线ç¨Aä¼ä¸ç´çå¾
thread线ç¨ç»æ¢ä¹åæä»thread.join()è¿åï¼å䏿§è¡ã线ç¨Threadé¤äºæä¾join()æ¹æ³ä¹å¤ï¼è¿æä¾äºjoin(long millis)åjoin(long millis,int nanos)两个å
·å¤è¶
æ¶åæ°çæ¹æ³ã
#### 5.ThreadLocalç使ç¨
ThreadLocalï¼å³çº¿ç¨åéï¼æ¯ä¸ä¸ªä»¥ThreadLocal对象为é®ãä»»æå¯¹è±¡ä¸ºå¼çåå¨ç»æãè¿ ä¸ªç»æè¢«é带å¨çº¿ç¨ä¸ï¼ä¹å°±æ¯è¯´ä¸ä¸ªçº¿ç¨å¯ä»¥æ ¹æ®ä¸ä¸ªThreadLocal对象æ¥è¯¢å°ç»å®å¨è¿ä¸ª 线ç¨ä¸çä¸ä¸ªå¼ã
```java
public class Profiler {
// ç¬¬ä¸æ¬¡get()æ¹æ³è°ç¨æ¶ä¼è¿è¡åå§å(妿setæ¹æ³æ²¡æè°ç¨)ï¼æ¯ä¸ªçº¿ç¨ä¼è°ç¨ä¸æ¬¡
private static final ThreadLocal TIME_THREADLOCAL = new ThreadLocal() {
protected Long initialValue() { return System.currentTimeMillis();}
};
public static final void begin() {
TIME_THREADLOCAL.set(System.currentTimeMillis());
}
public static final long end() {
return System.currentTimeMillis() - TIME_THREADLOCAL.get();
}
public static void main(String[] args) throws Exception {
Profiler.begin();
TimeUnit.SECONDS.sleep(1);
System.out.println("Cost: " + Profiler.end() + " mills");
}
}
```
Profilerå¯ä»¥è¢«å¤ç¨å¨æ¹æ³è°ç¨èæ¶ç»è®¡çåè½ä¸ï¼å¨æ¹æ³çå
¥å£åæ§è¡begin()æ¹æ³ï¼å¨
æ¹æ³è°ç¨åæ§è¡end()æ¹æ³ï¼å¥½å¤æ¯ä¸¤ä¸ªæ¹æ³çè°ç¨ä¸ç¨å¨ä¸ä¸ªæ¹æ³æè
ç±»ä¸ï¼æ¯å¦å¨AOP(é¢ åæ¹é¢ç¼ç¨)ä¸ï¼å¯ä»¥å¨æ¹æ³è°ç¨åçåå
¥ç¹æ§è¡begin()æ¹æ³ï¼è卿¹æ³è°ç¨åçåå
¥ç¹æ§è¡ end()æ¹æ³ï¼è¿æ ·ä¾æ§å¯ä»¥è·å¾æ¹æ³çæ§è¡èæ¶ã
### æä¹å®ç°å®ç°ä¸ä¸ªç产è
æ¶è´¹è
ï¼
#### 1.使ç¨Object.wait()åObject.notify()å®ç°
使ç¨queueä½ä¸ºä¸ä¸ªéåï¼åæ¾æ°æ®ï¼å¹¶ä¸ä½¿ç¨Synchronized忥éï¼æ¯æ¬¡åªè½åæ¶åå¨ä¸ä¸ªçº¿ç¨æ¥ç产æè
æ¶è´¹æ°æ®ï¼
çæçº¿ç¨åç°éå容é>10,ç产è
线ç¨å°±è¿å
¥waitingç¶æï¼ä¸æ¦æåå¾éåæ·»å æ°æ®ï¼é£ä¹å°±å¤éææçº¿ç¨ï¼ä¸»è¦æ¯ç产è
线ç¨èµ·æ¥æ¶è´¹ï¼ã
æ¶è´¹çº¿ç¨æ¶è´¹æ¶ï¼åç°éå容é==0ï¼ä¹ä¼ä¸»å¨è¿å
¥waitingç¶æã
伪代ç å¦ä¸ï¼
```java
LinkedList queue = new LinkedList<>();
void produce(Integer value) {
synchronized(queue) {//å éæ§å¶ï¼ä¿è¯å䏿¶é´ç¹ï¼åªè½æä¸ä¸ªçº¿ç¨çææè
æ¶è´¹
while(queue.size()>10) {
queue.waiting();
}
queue.add(value);
//å¤éæ¶è´¹è
线ç¨
queue.notifyAll();
}
}
Integer consumer() {
synchronized(queue) {//å éæ§å¶ï¼ä¿è¯å䏿¶é´ç¹ï¼åªè½æä¸ä¸ªçº¿ç¨çææè
æ¶è´¹
while(queue.size()==0) {
queue.waiting();
}
Integer value = queue.poll();
//å¤éç产è
线ç¨
queue.notifyAll();
return value;
}
}
```
宿´ä»£ç å¦ä¸ï¼
```java
public static void main(String[] args) {
Queue queue = new LinkedList<>();
final Customer customer = new Customer(queue);
final Producer producer = new Producer(queue);
ExecutorService pool = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++) {
pool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Integer a = customer.removeObject();
System.out.println("æ¶è´¹äºæ°æ® "+a);
}
});
pool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Random random = new Random();
Integer a = random.nextInt(1000);
System.out.println("çæäºæ°æ® "+a);
producer.addObject(a);
}
});
}
}
private static class Customer {
Queue queue;
Customer(Queue queue) { this.queue = queue; }
public Integer removeObject() {
synchronized (queue) {
try {
while (queue.size()==0) {
System.out.println("éå䏿²¡æå
ç´ äºï¼è¿è¡çå¾
");
queue.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
Integer number = queue.poll();
System.out.println("å¤éææç产线ç¨ï¼å½åqueue大尿¯" + queue.size());
queue.notifyAll();
return number;
}
}
}
private static class Producer {
Queue queue;
Producer(Queue queue) { this.queue = queue; }
public void addObject(Integer number) {
synchronized (queue) {
try {
while (queue.size()>10) {
queue.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
queue.add(number);
queue.notifyAll();
System.out.println("å¤éæææ¶è´¹çº¿ç¨ï¼å½åqueue大尿¯"+queue.size());
}
}
}
```
#### 2.使ç¨LockåConditionæ¥å®ç°
è°ç¨Object.wait()æ¹æ³å¯ä»¥è®©çº¿ç¨è¿å
¥çå¾
ç¶æï¼è¢«æ·»å å°Objectçmonitorçè§å¨ççå¾
éåä¸ï¼Object.notifyAll()å¯ä»¥å¤émonitorçè§å¨çå¾
éåä¸çææçº¿ç¨ã
èè°ç¨lockçnewCondition()æ¹æ³,å¯ä»¥è¿åä¸ä¸ªConditionObjectå®ä¾å¯¹è±¡ï¼æ¯ä¸ªConditionObjectå
å«ä¸ä¸ªé¾è¡¨ï¼åå¨çå¾
éåãå¯ä»¥è®¤ä¸ºä¸ä¸ªReentrantLockæä¸ä¸ªåæ¥éåï¼åæ¾æ²¡æè·å¾éç线ç¨ï¼ï¼åå¤ä¸ªçå¾
éåï¼åæ¾è°ç¨await()æ¹æ³ç线ç¨ï¼ã使ç¨Condition.singal()åCondition.singalAll()å¯ä»¥æ´å **ç²¾åçå¤é线ç¨**ï¼ä¹å°±æ¯å¤éç齿¯è¿ä¸ªCondition对åºççå¾
éåéé¢ç线ç¨ï¼èObject.notify()åObject.notifyAll()åªè½å¤éçå¾
éåä¸çææç线ç¨ã
```java
ReentrantLock lock = new ReentrantLock();
Condition customerQueue = lock.newCondition();
```
ReentrantLockçConditionç¸å
³çå®ç°

```java
abstract static class Sync extends AbstractQueuedSynchronizer {
final ConditionObject newCondition() {
return new ConditionObject();
}
}
//AQSå
é¨ç±» ConditionObject
public class ConditionObject implements Condition, java.io.Serializable {
private static final long serialVersionUID = 1173984872572414699L;
//é¾è¡¨å¤´ç»ç¹
private transient Node firstWaiter;
//é¾è¡¨å°¾ç»ç¹
private transient Node lastWaiter;
//çæ£çå建Condition对象
public ConditionObject() { }
}
```
æ¶è´¹è
-ç产è
å®ç°
```java
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition customerQueue = lock.newCondition();
Condition producerQueue = lock.newCondition();
Queue queue = new LinkedList<>();
final Customer customer = new Customer(lock,customerQueue, producerQueue,queue);
final Producer producer = new Producer(lock,customerQueue, producerQueue,queue);
ExecutorService pool = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++) {
pool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Integer a = customer.take();
// System.out.println("æ¶è´¹äºæ°æ® "+a);
}
});
pool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Random random = new Random();
Integer a = random.nextInt(1000);
// System.out.println("çæäºæ°æ® "+a);
producer.add(a);
}
});
}
}
private static class Customer {
private ReentrantLock lock;
private Condition customer;
private Condition producer;
private Queue queue;
Customer(ReentrantLock lock, Condition customer, Condition producer,Queue queue) {
this.lock = lock;
this.customer = customer;
this.producer = producer;
this.queue = queue;
}
public Integer take() {
lock.lock();
Integer element = null;
try {
while (queue.size() == 0) {
customer.await();
}
element = queue.poll();
System.out.println("æ¶è´¹è
线ç¨ååºæ¥å
ç´ "+element);
producer.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return element;
}
}
private static class Producer {
private ReentrantLock lock;
private Condition customer;
private Condition producer;
private Queue queue;
Producer(ReentrantLock lock, Condition customer, Condition producer,Queue queue) {
this.lock = lock;
this.customer = customer;
this.producer = producer;
this.queue = queue;
}
public void add( Integer element) {
lock.lock();
try {
while (queue.size() > 10) {
producer.await();
}
queue.add(element);
System.out.println("çæåçº¿ç¨æ·»å å
ç´ "+element);
customer.signalAll();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
```
#### 3.使ç¨BlockingQueueå®ç°
å©ç¨é»å¡éåBlockingQueueçç¹å¾è¿è¡çäº§åæ¶è´¹ç忥(å
¶å®é»å¡éåå
é¨ä¹æ¯åºäºLock,conditionå®ç°ç )
```java
public class BlockQueueRepository extends AbstractRepository implements Repository {
public BlockQueueRepository(int cap) {
//cap代表éåçæå¤§å®¹é
products = new LinkedBlockingQueue<>(cap);
}
@Override
public void put(T t) {
if (isFull()) {
log.info("repository is full, waiting for consume.....");
}
try {
//妿éåé¿åº¦å·²æ»¡ï¼é£ä¹ä¼é»å¡çå¾
((BlockingQueue) products).put(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public T take() {
T product = null;
if (isEmpty()) {
log.info("repository is empty, waiting for produce.....");
}
try {
//妿éåå
ç´ ä¸ºç©ºï¼é£ä¹ä¹ä¼é»å¡çå¾
product = (T) ((BlockingQueue) products).take();
} catch (InterruptedException e) {
e.printStackTrace();
}
return product;
}
}
```
### è°ä¸è°ä½ å¯¹çº¿ç¨æ± ççè§£ï¼
#### é¦å
çº¿ç¨æ± æä»ä¹ä½ç¨ï¼
* 1.æé«ååºé度ï¼å¦æçº¿ç¨æ± æç©ºé²çº¿ç¨çè¯ï¼å¯ä»¥ç´æ¥å¤ç¨è¿ä¸ªçº¿ç¨æ§è¡ä»»å¡ï¼èä¸ç¨å»å建ã
* 2.åå°èµæºå ç¨ï¼æ¯æ¬¡é½å建线ç¨é½éè¦ç³è¯·èµæºï¼è使ç¨çº¿ç¨æ± å¯ä»¥å¤ç¨å·²å建ç线ç¨ã
* 3.å¯ä»¥æ§å¶å¹¶åæ°ï¼å¯ä»¥éè¿è®¾ç½®çº¿ç¨æ± çæå¤§çº¿ç¨æ°éæ¥æ§å¶æå¤§å¹¶åæ°ï¼å¦ææ¯æ¬¡é½æ¯å建æ°çº¿ç¨ï¼æ¥äºå¤§éç请æ±ï¼å¯è½ä¼å 为å建ç线ç¨è¿å¤ï¼é æå
åæº¢åºã
* 4.æ´å æ¹ä¾¿æ¥ç®¡ç线ç¨èµæºã
#### çº¿ç¨æ± æåªäºåæ°ï¼
```java
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
```
##### 1.corePoolSize æ ¸å¿çº¿ç¨æ°
è¯¥çº¿ç¨æ± ä¸**æ ¸å¿çº¿ç¨æ°æå¤§å¼**ï¼æ·»å 任塿¶ï¼å³ä¾¿æç©ºé²çº¿ç¨ï¼åªè¦å½åçº¿ç¨æ± çº¿ç¨æ°());
}
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
```
ä¸å¥è¯æ»ç»å°±æ¯ï¼**çº¿ç¨æ°åºå®ï¼çå¾
éåæ éé¿**ã
å建ä¸ä¸ªçº¿ç¨æ± ï¼æ ¸å¿çº¿ç¨æ°ä¸æå¤§çº¿ç¨æ°å¼é½æ¯ä¼ å
¥åæ°nThreadsã坿§å¶çº¿ç¨æå¤§å¹¶åæ°ï¼è¶
åºç线ç¨ä¼å¨éåä¸çå¾
ï¼æ¯è¾éåéè¦æ§å¶å¹¶åéçæ
åµï¼ãä¸»è¦æ¯éè¿å°æ ¸å¿çº¿ç¨æ°è®¾ç½®ä¸ºä¸æå¤§çº¿ç¨æ°ç¸çå®ç°çãç¼ºç¹æ¯LinkedBlockingQueueéåçé»è®¤é¿åº¦æ¯Integer.MAX_VALUEï¼ä¹åå¨å
åæº¢åºçé£é©ã
**ä¸CachedThreadPoolçåºå«**ï¼
- å 为 corePoolSize == maximumPoolSize ï¼æä»¥**newFixedThreadPool**åªä¼åå»ºæ ¸å¿çº¿ç¨ã è**CachedThreadPool**å 为corePoolSize=0ï¼æä»¥åªä¼åå»ºéæ ¸å¿çº¿ç¨ã
- å¨ getTask() æ¹æ³ï¼å¦æéåéæ²¡æä»»å¡å¯åï¼çº¿ç¨ä¼ä¸ç´é»å¡å¨ LinkedBlockingQueue.take() ï¼çº¿ç¨ä¸ä¼è¢«åæ¶ã **CachedThreadPool**ç线ç¨ä¼å¨60såæ¶åã
- ç±äºçº¿ç¨ä¸ä¼è¢«åæ¶ï¼ä¼ä¸ç´å¡å¨é»å¡ï¼æä»¥**没æä»»å¡çæ
åµä¸ï¼ FixedThreadPoolå ç¨èµæºæ´å¤**ã
- é½å ä¹ä¸ä¼è§¦åæç»çç¥ï¼ä½æ¯åçä¸åãFixedThreadPoolæ¯å 为é»å¡éåå¯ä»¥å¾å¤§ï¼æå¤§ä¸ºIntegeræå¤§å¼ï¼ï¼æ
å ä¹ä¸ä¼è§¦åæç»çç¥ï¼CachedThreadPoolæ¯å ä¸ºçº¿ç¨æ± å¾å¤§ï¼æå¤§ä¸ºIntegeræå¤§å¼ï¼ï¼å ä¹ä¸ä¼å¯¼è´çº¿ç¨æ°éå¤§äºæå¤§çº¿ç¨æ°ï¼æ
å ä¹ä¸ä¼è§¦åæç»çç¥ã
##### newSingleThreadExecutor åçº¿ç¨æ±
```java
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
}
```
ä¸å¥è¯æ»ç»å°±æ¯ï¼**åçº¿ç¨æ± ï¼çå¾
éåæ éé¿ã**
å建ä¸ä¸ªå线ç¨åççº¿ç¨æ± ï¼å®åªä¼ç¨å¯ä¸çå·¥ä½çº¿ç¨æ¥æ§è¡ä»»å¡ï¼ä¿è¯ææä»»å¡æç
§æå®é¡ºåº(FIFO, LIFO, ä¼å
级)æ§è¡ãä¸»è¦æ¯éè¿å°æ ¸å¿çº¿ç¨æ°åæå¤§çº¿ç¨æ°é½è®¾ç½®ä¸º1æ¥å®ç°ã
##### newCachedThreadPoolå¯ç¼åçº¿ç¨æ±
å建ä¸ä¸ªå¯ç¼åçº¿ç¨æ± ï¼å¦æçº¿ç¨æ± é¿åº¦è¶
è¿å¤çéè¦ï¼å¯çµæ´»åæ¶ç©ºé²çº¿ç¨ï¼è¥æ å¯åæ¶ï¼åæ°å»ºçº¿ç¨ã使¯ç±äºæå¤§çº¿ç¨æ°è®¾ç½®çæ¯Integer.MAX_VALUEï¼åå¨å
åæº¢åºçé£é©ã
ä¸å¥è¯æ»ç»å°±æ¯ï¼**æå¤§çº¿ç¨æ°æ é大ï¼çº¿ç¨è¶
æ¶è¢«åæ¶**
```java
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue());
}
```
`CacheThreadPool`ç**è¿è¡æµç¨**å¦ä¸ï¼
1. æäº¤ä»»å¡è¿çº¿ç¨æ± ã
2. å 为**corePoolSize**为0çå
³ç³»ï¼ä¸åå»ºæ ¸å¿çº¿ç¨ï¼çº¿ç¨æ± æå¤§ä¸ºInteger.MAX_VALUEã
3. å°è¯å°ä»»å¡æ·»å å°**SynchronousQueue**éåã(éè¦æ³¨æçæ¯**SynchronousQueue**æ¬èº«ä¸åå¨ä»»å¡ï¼åªæ¯å°æ·»å ä»»å¡ç线ç¨å å
¥ä¸ä¸ªæ ä¸ï¼è¿è¡é»å¡çå¾
ï¼ç¶åçº¿ç¨æ± ä¸ç线ç¨ç©ºé²æ¶ï¼ä¼ä»æ ä¸ååºçº¿ç¨ï¼ååºçº¿ç¨æºå¸¦çä»»å¡ï¼è¿è¡æ§è¡ã)
4. 妿**SynchronousQueue**å
¥åæåï¼çå¾
被å½åè¿è¡ç线ç¨ç©ºé²åæåæ§è¡ã妿å½å没æç©ºé²çº¿ç¨ï¼é£ä¹å°±å建ä¸ä¸ªéæ ¸å¿çº¿ç¨ï¼ç¶åä»SynchronousQueueæåä»»å¡å¹¶å¨å½åçº¿ç¨æ§è¡ã
5. 妿**SynchronousQueue**å·²æä»»å¡å¨çå¾
ï¼å
¥åæä½å°ä¼é»å¡ã
å½éè¦æ§è¡å¾å¤**çæ¶é´**ç任塿¶ï¼CacheThreadPoolç线ç¨å¤ç¨çæ¯è¾é«ï¼ 伿¾èç**æé«æ§è½**ãèä¸çº¿ç¨60såä¼åæ¶ï¼æå³çå³ä½¿æ²¡æä»»å¡è¿æ¥ï¼CacheThreadPoolå¹¶ä¸ä¼å ç¨å¾å¤èµæºã
##### newScheduledThreadPool宿¶æ§è¡çº¿ç¨æ±
å建ä¸ä¸ªå®æ¶æ§è¡ççº¿ç¨æ± ï¼ä¸»è¦æ¯éè¿DelayedWorkQueueæ¥å®ç°ï¼è¯¥éåä¸çå
ç´ åªæå½å
¶æå®çå»¶è¿æ¶é´å°äºï¼æè½å¤ä»éåä¸è·åå°è¯¥å
ç´ ï¼ãæ¯æå®æ¶å卿æ§ä»»å¡æ§è¡ã使¯ç±äºæå¤§çº¿ç¨æ°è®¾ç½®çæ¯Integer.MAX_VALUEï¼åå¨å
åæº¢åºçé£é©ã
ä¸å¥è¯æ»ç»å°±æ¯ï¼çº¿ç¨æ°æ é大ï¼å®æ¶æ§è¡ã
```java
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}
```
##### 为ä»ä¹ä¸å»ºè®®å¤§å®¶ä½¿ç¨Executorsçåç§çº¿ç¨æ± å¢ï¼
ä¸»è¦æ¯newFixedThreadPoolånewSingleThreadExecutorççå¾
é忝LinkedBlockingQueueï¼é¿åº¦æ¯Integer.MAX_VALUE,ï¼å¯ä»¥è®¤ä¸ºæ¯æ é大çï¼å¦æå建çä»»å¡ç¹å«å¤ï¼å¯è½ä¼é æå
åæº¢åºãènewCachedThreadPoolånewScheduledThreadPoolçæå¤§çº¿ç¨æ°æ¯Integer.MAX_VALUEï¼å¦æå建çä»»å¡è¿å¤ï¼å¯è½ä¼å¯¼è´å建ç线ç¨è¿å¤ï¼ä»è导è´å
åæº¢åºã
æ©å±èµæï¼
[Javaçº¿ç¨æ± å®ç°åçåå
¶å¨ç¾å¢ä¸å¡ä¸çå®è·µ](https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html)
[SynchronousQueueå®ç°åç](https://zhuanlan.zhihu.com/p/29227508)
### çº¿ç¨æ± æåªäºç¶æï¼
çº¿ç¨æ± çå½å¨æï¼
- **RUNNING**ï¼è¡¨ç¤ºçº¿ç¨æ± å¤äºè¿è¡ç¶æï¼è¿æ¶åççº¿ç¨æ± å¯ä»¥æ¥åä»»å¡åå¤çä»»å¡ã弿¯-1ï¼
- **SHUTDOWN**ï¼è¡¨ç¤ºçº¿ç¨æ± 䏿¥åæ°ä»»å¡ï¼ä½ä»ç¶å¯ä»¥å¤çéåä¸çä»»å¡ï¼äºè¿å¶å¼æ¯0ãè°ç¨showdown()æ¹æ³ä¼è¿å
¥å°SHUTDOWNç¶æã
- **STOP**ï¼è¡¨ç¤ºçº¿ç¨æ± 䏿¥åæ°ä»»å¡ï¼ä¹ä¸å¤çéåä¸çä»»å¡ï¼åæ¶ä¸ææ£å¨æ§è¡ä»»å¡ç线ç¨ï¼å¼æ¯1ãè°ç¨showdownNow()æ¹æ³ä¼è¿å
¥å°STOPç¶æã
- **TIDYING**ï¼è¡¨ç¤ºææçä»»å¡é½å·²ç»ç»æ¢ï¼å¹¶ä¸å·¥ä½çº¿ç¨çæ°é为0ã弿¯2ãSHUTDOWNåSTOPç¶æççº¿ç¨æ± 任塿§è¡å®äºï¼å·¥ä½çº¿ç¨ä¹ä¸º0äºå°±ä¼è¿å
¥å°TIDYINGç¶æã
- **TERMINATED**ï¼è¡¨ç¤ºçº¿ç¨æ± å¤äºç»æ¢ç¶æã弿¯3

### æä¹æ ¹æ®ä¸å¡åºæ¯ç¡®å®çº¿ç¨æ± çåæ°corePoolSizeåmaximumPoolSizeï¼
#### æ¹æ³ä¸ 计ç®å¯éåä»»å¡
å 为æ¯è®¡ç®å¯éåä»»å¡ï¼å¯ä»¥ç解为æ¯ä¸ªä»»å¡å¨æ§è¡æé´åºæ¬æ²¡æIOæä½ï¼å
¨é¨é½å¨CPUæ¶é´ç䏿§è¡ãæä»¥å¯ä»¥ç解为CPUå°±æ¯æ»¡è½½çï¼CPUå©ç¨çå°±æ¯100%ï¼å
¶å®çº¿ç¨æ°çäºCPUæ°å°±å¯ä»¥çï¼ä½æ¯ç±äºéè¦èèå°è®¡ç®å¯éåççº¿ç¨æ°å¥½å¨ææ¶å 为åçä¸ä¸ªé¡µé误æè
å å
¶ä»åå èæåï¼æ¤æ¶åºè¯¥éè¦æä¸ä¸ªâé¢å¤âç空é²çº¿ç¨æ¥è·å¾æ¶é´çï¼ç¶åæ§è¡ï¼å¯ä»¥ç¡®ä¿å¨è¿ç§æ
åµä¸CPU卿ä¸ä¼ä¸æå·¥ä½ï¼å
åå©ç¨CPUã
```java
æä½³çº¿ç¨æ°=CPUçæ°é+1
```
#### æ¹æ³äº IOå¯éåä»»å¡
è¿ç§ä»»å¡å¨æ§è¡æ¶ï¼éè¦è¿è¡ä¸äºIOæä½ï¼æä»¥ä¸ºäºå
åå©ç¨CPUï¼åºè¯¥å¨çº¿ç¨è¿è¡IOæä½æ¶ï¼å°±è®©åºæ¶é´çï¼CPUè¿è¡ä¸ä¸æåæ¢ï¼æ§è¡å
¶ä»çº¿ç¨çä»»å¡ï¼ä¿è¯CPUå©ç¨çå°½å¯è½è¾¾å°100%ã
妿任塿50%çæ¶é´éè¦CPUæ§è¡ç¶æï¼å
¶ä»æ¶é´è¿è¡IOæä½ï¼åç¨åºæéçº¿ç¨æ°ä¸ºCPUæ°éç1é¤ä»¥0.5ï¼ä¹å°±æ¯2åã妿任塿20%çæ¶æ¶é´éè¦CPUæ§è¡ï¼å
¶ä»æ¶é´éè¦è¿è¡IOæä½ï¼æä½³çº¿ç¨æ°ä¹å°±æ¯1é¤ä»¥0.2ï¼ä¹å°±æ¯CPUæ°ç5åã
æä»¥å
¬å¼ä¸º
```java
æä½³çº¿ç¨æ° = CPUæ°é/(æ¯ä¸ªä»»å¡ä¸éè¦CPUæ§è¡çæ¶é´çæ¯ä¾)
= CPUæ°é/(CPUè¿è¡æ¶é´/任塿§è¡æ»æ¶é´)=CPUæ°é/(CPUè¿è¡æ¶é´/(CPUè¿è¡æ¶é´+IOæä½æ¶é´))
æä»¥æç»å
¬å¼ä¸º
æä½³çº¿ç¨æ°/CPUæ°é = CPUè¿è¡æ¶é´/(CPUè¿è¡æ¶é´+IOæä½æ¶é´)
```
##### ä¸è¶³
使¯å¨å®é
线ä¸è¿è¡çç¯å¢ä¸ï¼æ¯ä¸ªä»»å¡æ§è¡çæ¶é´æ¯åä¸ç¸åçï¼è䏿们å
¶å®æ¯ä¸å¤ªæ¹ä¾¿å»çæµæ¯ä¸ªä»»å¡æ§è¡æ¶éè¦çCPUæ§è¡æ¶é´ï¼IOæä½æ¶é´çï¼æä»¥è¿ç§æ¹æ³åªæ¯ä¸ç§ç论ã
#### æ¹æ³ä¸ 卿åçº¿ç¨æ±
è¿ç§å
¶å®æ¯ç¾å¢ä»ä»¬åçä¸ä¸ªçº¿ç¨æ± çæµå¹³å°ï¼ä¸»è¦æä»»å¡åæä¸¤ç§ï¼
##### 追æ±ååºæ¶é´çä»»å¡
ä¸ç§æ¯è¿½æ±ååºæ¶é´çä»»å¡ï¼ä¾å¦ä½¿ç¨çº¿ç¨æ± 对åèµ·å¤ä¸ªç½ç»è¯·æ±ï¼ç¶åå¯¹ç»æè¿è¡è®¡ç®ã è¿ç§ä»»å¡çæå¤§çº¿ç¨æ°éè¦è®¾ç½®å¤§ä¸ç¹ï¼ç¶åéå使ç¨åæ¥éåï¼éåä¸ä¸ç¼åä»»å¡ï¼ä»»å¡æ¥äºå°±ä¼è¢«æ§è¡ãå¤æçº¿ç¨æ± èµæºä¸å¤ç¨æ¶ï¼ä¸è¬æ¯åç°æ´»è·çº¿ç¨æ°/æå¤§çº¿ç¨æ°>éå¼(é»è®¤æ¯0.8)æ¶ï¼æè
æ¯çº¿ç¨æ± æåºçRejectedExecutå¼å¸¸æ¬¡æ°è¾¾å°éå¼ï¼å°±ä¼è¿è¡åè¦ãç¶åç¨åºåæ¶å°åè¦åï¼å¨æåéä¿®æ¹æ ¸å¿çº¿ç¨æ°ï¼æå¤§çº¿ç¨æ°ï¼éåç¸å
³çæä»¤ï¼æå¡å¨è¿è¡å¨æä¿®æ¹ã
##### 追æ±é«ååéçä»»å¡
å设说éè¦å®æèªå¨åçæä¸äºæ¥è¡¨ï¼ä¸éè¦èèååºæ¶é´ï¼åªæ¯å¸æå¦ä½ä½¿ç¨æéçèµæºï¼å°½å¯è½å¨å使¶é´å
å¤çæ´å¤çä»»å¡ï¼ä¹å°±æ¯ååéä¼å
çé®é¢ã
è¿ç§å°±æ¯ä½¿ç¨æçéåï¼å¯¹ä»»å¡è¿è¡ç¼åï¼ç¶å线ç¨è¿è¡å¹¶åæ§è¡ãå¤æçº¿ç¨æ± èµæºä¸å¤ç¨æ¶ï¼ä¸è¬æ¯åç°çå¾
éåä¸ç任塿°é/çå¾
éåçé¿åº¦>éå¼(é»è®¤æ¯0.8)æ¶ï¼æè
æ¯çº¿ç¨æ± æåºçRejectedExecutå¼å¸¸æ¬¡æ°è¾¾å°éå¼ï¼å°±ä¼è¿è¡åè¦ãç¶åç¨åºåæ¶å°åè¦åï¼å¨æåéä¿®æ¹æ ¸å¿çº¿ç¨æ°ï¼æå¤§çº¿ç¨æ°ï¼éåç¸å
³çæä»¤ï¼æå¡å¨è¿è¡å¨æä¿®æ¹ã
ThreadPoolExecutoræä¾äºå¦ä¸å 个publicçsetteræ¹æ³

è°ç¨corePoolSizeæ¹æ³ä¹åï¼çº¿ç¨æ± ä¼ç´æ¥è¦ç忥çcorePoolSizeå¼ï¼å¹¶ä¸åºäºå½åå¼ååå§å¼çæ¯è¾ç»æéåä¸åçå¤ççç¥ãï¼æ»å¾æ¥è¯´å°±æ¯ï¼å¤éå°è¡¥ççç¥ï¼
**å¯¹äºæ°corePoolSize<å½åå·¥ä½çº¿ç¨æ°çæ
åµï¼**
说ææå¤ä½çworker线ç¨ï¼æ¤æ¶ä¼åå½åidleç¶æçworker线ç¨åèµ·ä¸æè¯·æ±ä»¥å®ç°åæ¶ï¼å¤ä½çworkerå¨ä¸æ¬¡idelçæ¶åä¹ä¼è¢«åæ¶ã
**å¯¹äºæ°corePoolSize>å½åå·¥ä½çº¿ç¨æ°ä¸éå䏿任å¡çæ
åµï¼**
妿å½åéå䏿å¾
æ§è¡ä»»å¡ï¼åçº¿ç¨æ± ä¼å建æ°çworkerçº¿ç¨æ¥æ§è¡éåä»»å¡ã
setCorePoolSizeçæ¹æ³çæ§è¡æµç¨å
¥ä¸å¾æç¤ºï¼

æ©å±èµæï¼
[Javaå¹¶åï¼å
«ï¼è®¡ç®çº¿ç¨æ± æä½³çº¿ç¨æ°](https://www.cnblogs.com/jpfss/p/11016169.html)
### ThreadLocalæ¯ä»ä¹ï¼æä¹é¿å
å
åæ³é²ï¼
ä»å颿æä¸ï¼ThreadLocalä¼è¢«çè§£ä¸ºçº¿ç¨æ¬å°åå¨ï¼å°±æ¯å¯¹äºä»£ç ä¸çä¸ä¸ªåéï¼æ¯ä¸ªçº¿ç¨æ¥æè¿ä¸ªåéçä¸ä¸ªå¯æ¬ï¼è®¿é®åä¿®æ¹å®æ¶é½æ¯å¯¹å¯æ¬è¿è¡æä½ã
##### 使ç¨åºæ¯ï¼
ThreadLocal éç¨äºæ¯ä¸ªçº¿ç¨éè¦èªå·±ç¬ç«çå®ä¾ä¸è¯¥å®ä¾éè¦å¨å¤ä¸ªæ¹æ³ä¸è¢«ä½¿ç¨ï¼ä¹å³åéå¨çº¿ç¨é´é离è卿¹æ³æç±»é´å
±äº«çåºæ¯ã(ä¾å¦ï¼æ¹æ³ç´æ¥è°ç¨æ¶ä¼ éçåéè¿å¤ï¼ä¸ºäºä»£ç ç®æ´æ§ï¼å¯ä»¥ä½¿ç¨ThreadLocalï¼å¨åä¸ä¸ªæ¹æ³ä¸ï¼å°åéè¿è¡åå¨ï¼åä¸ä¸ªæ¹æ³ä¸åï¼è¿è¡ä½¿ç¨ã)
```java
public class A {
// æ¯ä¸ªçº¿ç¨æ¬å°å¯æ¬åå§å
private static ThreadLocal threadLocal = new ThreadLocal <>(). withInitial (() -> new UserData ());
public static void setUser (UserLogin user){
if (user == null )
return ;
UserData userData = threadLocal.get();
userData. setUserLogin (user);
}
public static UserLogin getUser (){
return threadLocal.get(). getUserLogin ();
}
}
```
##### å®ç°åç
å°±æ¯æ¯ä¸ªThreadæä¸ä¸ªThreadLocalMapï¼ç±»ä¼¼äºHashMapï¼å½è°ç¨ThreadLocal#set()æ¹æ³è¿è¡å弿¶ï¼å®é
䏿¯å
è·åå°å½åç线ç¨ï¼ç¶åè·å线ç¨çmapï¼æ¯ä¸ä¸ªThreadLocalMapç±»åï¼ç¶åä¼å¨è¿ä¸ªmap䏿·»å ä¸ä¸ªæ°çé®å¼å¯¹ï¼keyå°±æ¯æä»¬ThreadLocalåéçå°åï¼valueå°±æ¯æä»¬åçå¼ãThreadLocalMapä¸HashMapä¸åçæ¶ï¼è§£å³HashMap使ç¨çæ¯**弿¾å®åæ³**ï¼ä¹å°±æ¯å½åç°hashCode计ç®å¾å°æ°ç»ä¸æ å·²ç»åå¨äºå
ç´ åï¼ä¼ç»§ç»å¾åæ¾ï¼ç´å°æ¾å°ä¸ä¸ªç©ºçæ°ç»ä¸æ ï¼åå¨é®å¼å¯¹ã
```java
//ThreadLocalå®ä¾çèµå¼æ¹æ³
public void set(T value) {
//è·åå½å线ç¨
Thread t = Thread.currentThread();
//è·å线ç¨å¯¹åºçMap
ThreadLocalMap map = getMap(t);
//å°å¼åå
¥çº¿ç¨ç¹æçMapä¸
if (map != null)
//key为thiså°±æ¯å½åThreadLocalå¼ç¨åéçå°å
//valueå°±æ¯æä»¬è¦åå¨çå¼
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
//线ç¨çthreadLocalså®ä¾åéå°±æ¯Map
return t.threadLocals;
}
```
##### ThreadLocalä¸çEntryçkey使ç¨äºå¼±å¼ç¨ï¼ä¸ºä»ä¹ä½¿ç¨å¼±å¼ç¨ï¼

é¦å
å¨ä¸é¢ç±»Aç代ç ä¸ï¼ç±»A䏿ä¸ä¸ªThreadLocalç±»åçåé
å®ä»¬çå¼ç¨é¾å¦ä¸ï¼
```java
ThreadLocalåéæå¨çç±»çå®ä¾(代ç ä¸Açå®ä¾)->ThreadLocal
æ§è¡ä»£ç ç线ç¨->线ç¨ç¬æçThreadLocalMap->å¼ç¨çkeyå°±æ¯ThreadLocal
```
å¯ä»¥çå°ThreadLocalåéä¸ä»
被æå¨çç±»Açå®ä¾æå¼ç¨ï¼è¿è¢«æ§è¡ççº¿ç¨æå¼ç¨ï¼
1.å¦æä½¿ç¨å¼ºå¼ç¨ï¼ä¹å°±æ¯çº¿ç¨å¯¹ThreadLocalåéæ¯å¼ºå¼ç¨ï¼é£ä¹å³ä¾¿å®ä¾Aè¢«åæ¶äºï¼åªè¦çº¿ç¨è¿æ²¡æè¢«åæ¶ï¼çº¿ç¨çThreadLocalMapè¿ä¼å¼ç¨è¿ä¸ªkey(ä¹å°±æ¯è¿ä¸ªThreadLocaléå)ï¼å¯¼è´è¿ä¸ªkey 没æè¢«åæ¶ï¼é æå
åæ³é²ã
2.å¦æä½¿ç¨å¼±å¼ç¨ï¼ä¸ä¼å½±åkeyçåæ¶ï¼ä¹å°±æ¯ä¸ä¼å½±åå¼ç¨äºThreadLocalçå®ä¾å¯¹è±¡çåæ¶ã
使¯å³ä¾¿ä½¿ç¨å¼±å¼ç¨ï¼ThreadLocalMap对valueçå¼ç¨æ¯å¼ºå¼ç¨(ä¸è¾¹valueæ¯å±é¨åéï¼ä¹ä¸è½ç¨å¼±å¼ç¨ï¼é£æ ·å¨ç¨å°çæ¶åå°±ä¼è¢«)ï¼ä½æ¯valueä¾ç¶ä¸ä¼è¢«åæ¶ï¼ä¼é æå
åæ³é²ã
é常æ¥è¯´ï¼valueåæ¶çæ¶æºæä¸¤ä¸ªï¼
1.æä»¬å¨ç¨å®ThreadLocalåï¼åºè¯¥éµå¾ªè§èæå¨è°ç¨ThreadLocal#remove()对é®å¼å¯¹valueéæ¾ï¼è¿æ ·å¯ä»¥ä½¿valueè¢«åæ¶ã
2.æ¤çº¿ç¨å¨å
¶ä»å¯¹è±¡ä¸ä½¿ç¨ThreadLocal对线ç¨ThreadLocalMapè¿è¡set()åget()æ¶,ç±äºéè¦è¿è¡å¼æ¾å®åæ³è¿è¡æ¢æµï¼ä¼å¯¹æ²¿éè¿æçé®å¼å¯¹(å°±æ¯key为nullçé®å¼å¯¹)è¿è¡æ¸
é¤ã以åset()æ¹æ³è§¦åçcleanSomeSlots()æ¹æ³å¯¹è¿æé®å¼å¯¹è¿è¡æ¸
é¤ã
[ãä¸ç¯æç« ï¼ä»æºç æ·±å
¥è¯¦è§£ThreadLocalå
åæ³æ¼é®é¢ã](https://www.jianshu.com/p/dde92ec37bd1)
### Randomç±»åéæºæ°çåçæ¯ä»ä¹ï¼
é¦å
å¨åå§åRandomå®ä¾çæ¶å就伿 ¹æ®å½åçæ¶é´æ³çæä¸ä¸ªç§åæ°seedã
```java
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
```
ç¶åæ¯æ¬¡åéæºæ°æ¶æ¯æ¿seedä¹ä»¥ä¸ä¸ªåºå®å¼multiplierï¼ä½ä¸ºéæºæ°ã
```java
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
```
使¯è¿æ ·çè¯ï¼å¤çº¿ç¨å¹¶å使ç¨Math.randomåéæºæ°æ¶ï¼åä¸ä¸ªæ¶é´ç¹åå°çéæºæ°ä¸æ ·çæ¦ç伿¯è¾å¤§ãæä»¥å¯ä»¥ä½¿ç¨ThreadLocalRandom.current().nextInt()æ¹æ³å»åéæºæ°ãæ¯ä¸ªçº¿ç¨ç¬¬ä¸æ¬¡è°ç¨ThreadLocalRandomdçcurrent()æ¹æ³æ¶ï¼ä¼ä¸ºè¿ä¸ªçº¿ç¨çæä¸ä¸ªçº¿ç¨ç¬ç«çç§åæ°seedï¼è¿æ ·å¤çº¿ç¨å¹¶å读åéæºæ°æ¶ï¼å¯ä»¥ä¿è¯åå°çéæºæ°é½æ¯ä¸ä¸æ ·çã
```java
public static ThreadLocalRandom current() {
//夿è¿ä¸ªçº¿ç¨æ¯å¦çæç§å
if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
localInit();
return instance;
}
//为è¿ä¸ªçº¿ç¨çæä¸ä¸ªç§åseedï¼å¹¶ä¸å°ç§åseedï¼å线ç¨å·²çæç§åçæ å¿ åå¨å°Unsafeç±»ä¸
static final void localInit() {
int p = probeGenerator.addAndGet(PROBE_INCREMENT);
int probe = (p == 0) ? 1 : p; // skip 0
long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
Thread t = Thread.currentThread();
UNSAFE.putLong(t, SEED, seed);
UNSAFE.putInt(t, PROBE, probe);
}
//è·åéæºæ°ï¼æ ¹æ®å½åç§å计ç®éæºæ°
public int nextInt(int origin, int bound) {
if (origin >= bound)
throw new IllegalArgumentException(BadRange);
return internalNextInt(origin, bound);
}
final int internalNextInt(int origin, int bound) {
int r = mix32(nextSeed());
if (origin < bound) {
int n = bound - origin, m = n - 1;
if ((n & m) == 0)
r = (r & m) + origin;
else if (n > 0) {
for (int u = r >>> 1;
u + m - (r = u % n) < 0;
u = mix32(nextSeed()) >>> 1)
;
r += origin;
}
else {
while (r < origin || r >= bound)
r = mix32(nextSeed());
}
}
return r;
}
```
### åµå°¸è¿ç¨ï¼å¤å¿è¿ç¨ï¼å®æ¤è¿ç¨æ¯ä»ä¹ï¼
åµå°¸è¿ç¨ï¼é常æ¥è¯´ï¼ä½¿ç¨fork()ç³»ç»è°ç¨ä»ä¸ä¸ªç¶è¿ç¨å建åºä¸ä¸ªåè¿ç¨ï¼åè¿ç¨éåºï¼æ¯éè¦ç¶è¿ç¨è°ç¨wait()æè
æ¯waitpid()彿°æ¥åæ¶åè¿ç¨çèµæºï¼å¦æç¶è¿ç¨æ²¡æè°ç¨ï¼åè¿ç¨çä¿¡æ¯å°±ä¼ä¸ç´å¨å
åä¸ï¼èä¸ä¼è¢«åæ¶ï¼åæåµå°¸è¿ç¨ã
å¤å¿è¿ç¨ï¼å°±æ¯ç¶è¿ç¨å
éåºäºï¼å®çåè¿ç¨ä¼è¢«initè¿ç¨æ¥ç®¡ï¼ç±å®æ¥æ¶éåè¿ç¨çç¶æã(initè¿ç¨æ¯å
æ ¸å¯å¨æ¶ï¼åå»ºåºæ¥çè¿ç¨ï¼æ¯ä¸ä¸ªä»¥root身份è¿è¡çæ®éç¨æ·è¿ç¨ï¼æ¯æ°¸è¿ä¸ä¼åæ¢çã)
宿¤è¿ç¨æ¯è±ç¦»äºç»ç«¯å¹¶ä¸å¨åå°è¿è¡çè¿ç¨ï¼è±ç¦»ç»ç«¯æ¯ä¸ºäºé¿å
å°å¨æ§è¡çè¿ç¨ä¸çä¿¡æ¯æå°å¨ç»ç«¯ä¸ï¼å¹¶ä¸è¿ç¨ä¹ä¸ä¼è¢«ä»»ä½ç»ç«¯æäº§ççç»ç«¯ä¿¡æ¯æææã
### BlockingQueueçåçæ¯æä¹æ ·çï¼
https://www.cnblogs.com/tjudzj/p/4454490.html
### è¿ç¨é´éä¿¡çæ¹å¼
https://network.51cto.com/art/201911/606827.htm?mobile