# ç®å½
* [åºç¡æ¦å¿µ](#åºç¡æ¦å¿µ)
* [è¿ç¨ä¸çº¿ç¨](#è¿ç¨ä¸çº¿ç¨)
* [å线ç¨ä¸å¤çº¿ç¨](#å线ç¨ä¸å¤çº¿ç¨)
* [å®ç°çº¿ç¨ç4䏿¹å¼](#å®ç°çº¿ç¨ç4䏿¹å¼)
* [thread.start()årunnable.run()çåºå«](#thread.start()årunnable.run()çåºå«)
* [ThreadåRunnableçå¼å](#ThreadåRunnableçå¼å)
* [线ç¨çåºæ¬æä½](#线ç¨çåºæ¬æä½)
* [线ç¨çä¼å
级ä¸å®æ¤çº¿ç¨](#线ç¨çä¼å
级ä¸å®æ¤çº¿ç¨)
* [synchronizedå
³é®å](#synchronizedå
³é®å)
* [å®ä¾éä¸å
¨å±é](#å®ä¾éä¸å
¨å±é)
* [waitånotify](#waitånotify)
* [线ç¨ç让æ¥yeild](#线ç¨ç让æ¥yeild)
* [线ç¨çä¼ç sleep](#线ç¨çä¼ç sleep)
* [Threadä¸çjoin](#Threadä¸çjoin)
* [线ç¨ç䏿interrupt](线ç¨ç䏿interrupt)
* [线ç¨çç¶æä¸è½¬æ¢](#线ç¨çç¶æä¸è½¬æ¢)
* [ç产è
æ¶è´¹è
é®é¢](#ç产è
æ¶è´¹è
é®é¢)
* [é©å线ç¨](#é©å线ç¨)
* [线ç¨ä¸çå¼å¸¸](#线ç¨ä¸çå¼å¸¸)
* [çº¿ç¨æ± ](#çº¿ç¨æ± )
* [建议](#建议)
### åºç¡æ¦å¿µ
#### è¿ç¨ä¸çº¿ç¨
`è¿ç¨ï¼Processï¼`æ¯è®¡ç®æºä¸çç¨åºå
³äºææ°æ®éåä¸ç䏿¬¡è¿è¡æ´»å¨ï¼æ¯ç³»ç»è¿è¡èµæºåé
åè°åº¦çåºæ¬åä½ï¼æ¯æä½ç³»ç»ç»æçåºç¡ã å¨å½ä»£é¢å线ç¨è®¾è®¡çè®¡ç®æºç»æä¸ï¼è¿ç¨æ¯çº¿ç¨ç容å¨ãç¨åºæ¯æä»¤ãæ°æ®åå
¶ç»ç»å½¢å¼çæè¿°ï¼è¿ç¨æ¯ç¨åºçå®ä½ãæ¯è®¡ç®æºä¸çç¨åºå
³äºææ°æ®éåä¸ç䏿¬¡è¿è¡æ´»å¨ï¼æ¯ç³»ç»è¿è¡èµæºåé
åè°åº¦çåºæ¬åä½ï¼æ¯æä½ç³»ç»ç»æçåºç¡ãç¨åºæ¯æä»¤ãæ°æ®åå
¶ç»ç»å½¢å¼çæè¿°ï¼è¿ç¨æ¯ç¨åºçå®ä½ãè¿ç¨ä¹é´éè¿TCP/IPçç«¯å£æ¥å®ç°ç¸äºäº¤äºã
`线ç¨ï¼threadï¼`æ¯æä½ç³»ç»è½å¤è¿è¡è¿ç®è°åº¦çæå°åä½ãå®è¢«å
å«å¨è¿ç¨ä¹ä¸ï¼æ¯è¿ç¨ä¸çå®é
è¿ä½åä½ã䏿¡çº¿ç¨æçæ¯è¿ç¨ä¸ä¸ä¸ªåä¸é¡ºåºçæ§å¶æµï¼ä¸ä¸ªè¿ç¨ä¸å¯ä»¥å¹¶åå¤ä¸ªçº¿ç¨ï¼æ¯æ¡çº¿ç¨å¹¶è¡æ§è¡ä¸åçä»»å¡ï¼å¤ä¸ªçº¿ç¨å
±äº«æ¬è¿ç¨çèµæºã线ç¨çéä¿¡å°±æ¯è¾ç®åï¼æä¸å¤§åå
±äº«çå
åï¼åªè¦å¤§å®¶çæéæ¯åä¸ä¸ªå°±å¯ä»¥çå°åèªçå
åã
`å°ç»`ï¼
1. è¿ç¨è¦åé
ä¸å¤§é¨åçå
åï¼è线ç¨åªéè¦åé
ä¸é¨åæ å°±å¯ä»¥äº
2. ä¸ä¸ªç¨åºè³å°æä¸ä¸ªè¿ç¨,ä¸ä¸ªè¿ç¨è³å°æä¸ä¸ªçº¿ç¨
3. è¿ç¨æ¯èµæºåé
çæå°åä½ï¼çº¿ç¨æ¯ç¨åºæ§è¡çæå°åä½
4. ä¸ä¸ªçº¿ç¨å¯ä»¥åå»ºåæ¤éå¦ä¸ä¸ªçº¿ç¨ï¼åä¸ä¸ªè¿ç¨ä¸çå¤ä¸ªçº¿ç¨ä¹é´å¯ä»¥å¹¶åæ§è¡
`å¹¶å`ï¼ å¯¹äºåæ ¸cpuæ¥è¯´ï¼å¤çº¿ç¨å¹¶ä¸æ¯åæ¶è¿è¡çï¼æä½ç³»ç»å°æ¶é´åæäºå¤ä¸ªæ¶é´ç(ææ¶é´ååææä¼å
级ï¼JVMæä¼å
级)ï¼å¤§æ¦ååçåé
ç»çº¿ç¨ï¼å°è¾¾æä¸ªçº¿ç¨çæ¶é´æ®µï¼è¯¥çº¿ç¨è¿è¡ï¼å
¶ä½æ¶é´å¾
å½ï¼è¿æ ·ä»å¾®è§ä¸çï¼ä¸ä¸ªçº¿ç¨æ¯èµ°èµ°ååçï¼å®è§æå®ä¸ï¼å¨æä¸æ¶å»ä¼¼ä¹ææçº¿ç¨é½å¨è¿è¡ã并忝é对æ¶é´ç段æ¥è¯´çï¼å¨æä¸ªæ¶é´æ®µå
å¤ä¸ªçº¿ç¨å¤äºrunnableå°runningä¹é´ï¼ä½æ¯ä¸ªæ¶å»åªæä¸ä¸ªçº¿ç¨å¨runningï¼è¿å«åå¹¶åã
#### å线ç¨ä¸å¤çº¿ç¨
å线ç¨å°±æ¯è¿ç¨ä¸åªæä¸ä¸ªçº¿ç¨ãå线ç¨å¨ç¨åºæ§è¡æ¶ï¼æèµ°çç¨åºè·¯å¾æç
§è¿ç»é¡ºåºæä¸æ¥ï¼åé¢çå¿
é¡»å¤ç好ï¼åé¢çæä¼æ§è¡ã
```java
// å线ç¨å®ä¾
public class SingleThread {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
```
å¤ä¸ªçº¿ç¨ç»æçç¨åºç§°ä¸ºå¤çº¿ç¨ç¨åºã常è§çå¤çº¿ç¨ç¨åºå¦ï¼GUIåºç¨ç¨åºãI/Oæä½ãç½ç»å®¹å¨çã
### å®ç°çº¿ç¨ç4䏿¹å¼
1. ç»§æ¿Threadç±»
2. å®ç°Runnableæ¥å£
3. å®ç°Callableæ¥å£(æè¿åå¼)
4. éè¿çº¿ç¨æ± æ¥å®ç°ExecuteService
```java
public class NewThreadThread {
public static void main(String[] args) {
new NewThread().start();
}
}
// ç»§æ¿èªThreadç±»
class NewThread extends Thread {
@Override
public void run() {
System.out.println("Thread running");
}
}
```
```java
public class NewThreadRunnable {
public static void main(String[] args) {
// runæ¹æ³è¿è¡
new NewRunnable().run();
// startæ¹æ³è¿è¡
NewRunnable newRunnable = new NewRunnable();
Thread thread = new Thread(newRunnable);
thread.start();
// è¾åº
/**
* main running
* Thread-0 running
*/
}
}
// å®ç°runnableæ¥å£
class NewRunnable implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " running");
}
}
```
```java
public class NewThreadCallable {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Callable newCallable = new NewCallable();
FutureTask futureTask = new FutureTask(newCallable);
Thread thread = new Thread(futureTask);
thread.start();
Object result = futureTask.get();
System.out.println(String.valueOf(result));
Callable newCallable2 = new NewCallable2();
FutureTask task = new FutureTask(newCallable2);
new Thread(task).start();
Integer i = task.get();
System.out.println(i);
}
}
// å®ç°Callableæ¥å£
class NewCallable implements Callable {
@Override
public Object call() throws Exception {
return "Hello World";
}
}
class NewCallable2 implements Callable {
@Override
public Integer call() throws Exception {
return 1;
}
}
```
```java
public class NewThreadExecutorService {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
});
}
pool.shutdown();
}
}
```
#### ThreadåRunnableçå¼å
* Thread å Runnable çç¸åç¹ï¼é½æ¯âå¤çº¿ç¨çå®ç°æ¹å¼âã
* Thread å Runnable çä¸åç¹ï¼
* Thread æ¯ç±»ï¼èRunnableæ¯æ¥å£ï¼Threadæ¬èº«æ¯å®ç°äºRunnableæ¥å£çç±»ãæä»¬ç¥éâä¸ä¸ªç±»åªè½æä¸ä¸ªç¶ç±»ï¼ä½æ¯å´è½å®ç°å¤ä¸ªæ¥å£âï¼å æ¤Runnableå
·ææ´å¥½çæ©å±æ§ãæ¤å¤ï¼Runnableè¿å¯ä»¥ç¨äºâèµæºçå
±äº«âãå³ï¼å¤ä¸ªçº¿ç¨é½æ¯åºäºæä¸ä¸ªRunnable对象建ç«çï¼å®ä»¬ä¼å
±äº«Runnable对象ä¸çèµæºï¼åéï¼ãé常ï¼å»ºè®®éè¿âRunnableâå®ç°å¤çº¿ç¨ï¼
#### thread.start()årunnable.run()çåºå«
Thread类继æ¿äºRunnableæ¥å£ï¼è°ç¨start()æ¹æ³ä¼å¯å¨ä¸ä¸ªæ°ççº¿ç¨æ¥æ§è¡ç¸åºçrun()æ¹æ³ï¼run()æ¹æ³åæ®éçæåæ¹æ³ä¸æ ·ï¼å¯ä»¥è¢«éå¤è°ç¨ï¼ä¼å¨å½å线ç¨ä¸æ§è¡è¯¥æ¹æ³ï¼èä¸ä¼å¯å¨æ°ç线ç¨ã(åèä¸é¢éè¿å®ç°Runnableæ¥å£æ¥å®ç°æ°çº¿ç¨)
### 线ç¨çä¼å
级ä¸å®æ¤çº¿ç¨
> 线ç¨çä¼å
级
Javaä¸ç线ç¨ä¼å
级çèå´æ¯1ï½10ï¼é»è®¤çä¼å
级æ¯5ï¼10ææé«ã线ç¨çä¼å
级å
·æä»¥ä¸ç¹æ§ï¼
`æ¦çæ§`: âé«ä¼å
级线ç¨â被åé
CPUçæ¦çé«äºâä½ä¼å
级线ç¨â
`éæºæ§`: æ ¹æ®æ¶é´ç轮循è°åº¦ï¼è½å¤å¹¶åæ§è¡,æ è®ºæ¯æ¯çº§å«ç¸åè¿æ¯ä¸åï¼çº¿ç¨è°ç¨é½ä¸ä¼ç»å¯¹æç
§ä¼å
级æ§è¡ï¼æ¯æ¬¡æ§è¡ç»æé½ä¸ä¸æ ·ï¼è°åº¦ç®æ³æ è§å¾å¯å¾ªï¼æä»¥çº¿ç¨ä¹é´ä¸è½æå
åä¾èµå
³ç³»ãæ æ¶é´ç轮循æºå¶æ¶ï¼é«çº§å«ç线ç¨ä¼å
æ§è¡ï¼å¦æä½çº§å«ççº¿ç¨æ£å¨è¿è¡æ¶ï¼æé«çº§å«çº¿ç¨å¯è¿è¡ç¶æï¼å伿§è¡å®ä½çº§å«çº¿ç¨ï¼å廿§è¡é«çº§å«çº¿ç¨ã妿ä½çº§å«çº¿ç¨å¤äºçå¾
ãç¡ç ãé»å¡ç¶æï¼æè
è°ç¨yield()彿°è®©å½åè¿è¡çº¿ç¨åå°å¯è¿è¡ç¶æï¼ä»¥å
许å
·æç¸åä¼å
级æè
é«çº§å«çå
¶ä»çº¿ç¨è·å¾è¿è¡æºä¼ãå æ¤ï¼ä½¿ç¨yield()çç®çæ¯è®©ç¸åä¼å
级ç线ç¨ä¹é´è½éå½ç轮转æ§è¡ã使¯ï¼å®é
䏿 æ³ä¿è¯yield()è¾¾å°è®©æ¥ç®çï¼å 为让æ¥ç线ç¨è¿æå¯è½è¢«çº¿ç¨è°åº¦ç¨åºå次éä¸ãç»è®ºï¼yield()仿ªå¯¼è´çº¿ç¨è½¬å°çå¾
/ç¡ç /é»å¡ç¶æãå¨å¤§å¤æ°æ
åµä¸ï¼yield()å°å¯¼è´çº¿ç¨ä»è¿è¡ç¶æè½¬å°å¯è¿è¡ç¶æï¼ä½æå¯è½æ²¡æææã
> ç¨æ·çº¿ç¨ä¸å®æ¤çº¿ç¨
å¨Javaä¸æä¸¤ç±»çº¿ç¨ï¼User Thread(ç¨æ·çº¿ç¨)ãDaemon Thread(宿¤çº¿ç¨)
ç¨ä¸ªæ¯è¾éä¿çæ¯å¦ï¼ä»»ä½ä¸ä¸ªå®æ¤çº¿ç¨é½æ¯æ´ä¸ªJVM䏿æé宿¤çº¿ç¨çä¿å§ãåªè¦å½åJVMå®ä¾ä¸å°åå¨ä»»ä½ä¸ä¸ªé宿¤çº¿ç¨æ²¡æç»æï¼å®æ¤çº¿ç¨å°±å
¨é¨å·¥ä½ï¼åªæå½æåä¸ä¸ªé宿¤çº¿ç¨ç»ææ¶ï¼å®æ¤çº¿ç¨éçJVMä¸åç»æå·¥ä½ãDaemonçä½ç¨æ¯ä¸ºå
¶ä»çº¿ç¨çè¿è¡æä¾ä¾¿å©æå¡ï¼å®æ¤çº¿ç¨æå
¸åçåºç¨å°±æ¯ `GC (åå¾åæ¶å¨)`ï¼å®å°±æ¯ä¸ä¸ªå¾ç§°èç宿¤è
ãUseråDaemon两è
å 乿²¡æåºå«ï¼å¯ä¸çä¸åä¹å¤å°±å¨äºèææºç离å¼ï¼å¦æ User Threadå·²ç»å
¨é¨éåºè¿è¡äºï¼åªå©ä¸Daemon Threadåå¨äºï¼èææºä¹å°±éåºäºã å 为没æäºè¢«å®æ¤è
ï¼Daemonä¹å°±æ²¡æå·¥ä½å¯åäºï¼ä¹å°±æ²¡æç»§ç»è¿è¡ç¨åºçå¿
è¦äºã
å¼å¾ä¸æçæ¯ï¼å®æ¤çº¿ç¨å¹¶éåªæèææºå
鍿ä¾ï¼ç¨æ·å¨ç¼åç¨åºæ¶ä¹å¯ä»¥èªå·±è®¾ç½®å®æ¤çº¿ç¨ãä¸é¢çæ¹æ³å°±æ¯ç¨æ¥è®¾ç½®å®æ¤çº¿ç¨çã
```java
// è®¾å® daemonThread 为 宿¤çº¿ç¨ï¼default false(é宿¤çº¿ç¨)
daemonThread.setDaemon(true);
// éªè¯å½åçº¿ç¨æ¯å¦ä¸ºå®æ¤çº¿ç¨ï¼è¿å true åä¸ºå®æ¤çº¿ç¨
daemonThread.isDaemon();
```
è¿éæå ç¹éè¦æ³¨æï¼
1. thread.setDaemon(true)å¿
é¡»å¨thread.start()ä¹å设置ï¼å¦åä¼è·åºä¸ä¸ªIllegalThreadStateExceptionå¼å¸¸ãä½ ä¸è½ææ£å¨è¿è¡ç常è§çº¿ç¨è®¾ç½®ä¸ºå®æ¤çº¿ç¨ã
2. å¨Daemon线ç¨ä¸äº§ççæ°çº¿ç¨ä¹æ¯Daemonçã
3. ä¸è¦è®¤ä¸ºææçåºç¨é½å¯ä»¥åé
ç»Daemonæ¥è¿è¡æå¡ï¼æ¯å¦è¯»åæä½æè
计ç®é»è¾ã
*é£ä¹å®æ¤çº¿ç¨çä½ç¨æ¯ä»ä¹ï¼*
举ä¾ï¼ GCåå¾åæ¶çº¿ç¨ï¼å°±æ¯ä¸ä¸ªç»å
¸ç宿¤çº¿ç¨ï¼å½æä»¬çç¨åºä¸ä¸åæä»»ä½è¿è¡çThread,ç¨åºå°±ä¸ä¼å产çåå¾ï¼åå¾åæ¶å¨ä¹å°±æ äºå¯åï¼æä»¥å½åå¾åæ¶çº¿ç¨æ¯JVMä¸ä»
å©ççº¿ç¨æ¶ï¼åå¾åæ¶çº¿ç¨ä¼èªå¨ç¦»å¼ãå®å§ç»å¨ä½çº§å«çç¶æä¸è¿è¡ï¼ç¨äºå®æ¶çæ§å管çç³»ç»ä¸çå¯åæ¶èµæºã
åºç¨åºæ¯ï¼ï¼1ï¼æ¥ä¸ºå
¶å®çº¿ç¨æä¾æå¡æ¯æçæ
åµï¼ï¼2ï¼ æè
å¨ä»»ä½æ
åµä¸ï¼ç¨åºç»ææ¶ï¼è¿ä¸ªçº¿ç¨å¿
é¡»æ£å¸¸ä¸ç«å»å
³éï¼å°±å¯ä»¥ä½ä¸ºå®æ¤çº¿ç¨æ¥ä½¿ç¨ï¼åä¹ï¼å¦æä¸ä¸ªæ£å¨æ§è¡æä¸ªæä½ç线ç¨å¿
é¡»è¦æ£ç¡®å°å
³éæå¦åå°±ä¼åºç°ä¸å¥½çåæçè¯ï¼é£ä¹è¿ä¸ªçº¿ç¨å°±ä¸è½æ¯å®æ¤çº¿ç¨ï¼èæ¯ç¨æ·çº¿ç¨ãé叏齿¯äºå
³é®çäºå¡ï¼æ¯æ¹è¯´ï¼æ°æ®åºå½å
¥æè
æ´æ°ï¼è¿äºæä½é½æ¯ä¸è½ä¸æçã
JVM ç¨åºå¨ä»ä¹æ
åµä¸è½å¤æ£å¸¸éåºï¼
The Java Virtual Machine exits when the only threads running are all daemon threads.
ä¸é¢è¿å¥è¯æ¥èª JDK 宿¹ææ¡£ï¼æææ¯ï¼å¦æ JVM 䏿²¡æä¸ä¸ªæ£å¨è¿è¡çé宿¤çº¿ç¨ï¼è¿ä¸ªæ¶åï¼JVM ä¼éåºãæ¢å¥è¯è¯´ï¼å®æ¤çº¿ç¨æ¥æèªå¨ç»æèªå·±çå½å¨æçç¹æ§ï¼èé宿¤çº¿ç¨ä¸å
·å¤è¿ä¸ªç¹ç¹
### 线ç¨çåºæ¬æä½
* thread.start()线ç¨å¯å¨è¿è¡
* thread.run()å¨å½å线ç¨ä¸è¿è¡runæ¹æ³
* Thread.currentThread()è·åå½å线ç¨ï¼getName()è·ååå
### synchronizedå
³é®å
> synchronizedæ¹æ³
```java
public synchronized void foo() {
System.out.println("synchronized methoed");
}
```
> synchronized代ç å
```java
public void foo() {
synchronized (this) {
System.out.println("synchronized methoed");
}
}
```
* synchronized代ç åä¸çthisæ¯æå½å对象ãä¹å¯ä»¥å°thisæ¿æ¢æå
¶ä»å¯¹è±¡ï¼ä¾å¦å°thisæ¿æ¢æobjï¼åfoo2()卿§è¡synchronized(obj)æ¶å°±è·åçæ¯objç忥éã
* synchronized代ç åä¸XXClass.classæ¯æè¿ä¸ªç±»ï¼æ°å»ºå¤ä¸ªå®ä¾æ¥è®¿é®åæ¥æ¹æ³æåæ¥ä»£ç åä¹ä¼è¢«é»å¡
* synchronized代ç åå¯ä»¥æ´ç²¾ç¡®çæ§å¶å²çªéå¶è®¿é®åºåï¼ææ¶åè¡¨ç°æ´é«æçã
> synchronizedå
³é®å使ç¨åå
1. å½ä¸ä¸ªçº¿ç¨è®¿é®ä¸ä¸ªå¯¹è±¡çsynchronizedæ¹æ³æè
synchronized代ç åæ¶ï¼å
¶ä»çº¿ç¨å¯¹`该对象`ç该synchronizedæ¹æ³æè
synchronized代ç åç访é®å°è¢«é»å¡ã
2. å½ä¸ä¸ªçº¿ç¨è®¿é®ä¸ä¸ªå¯¹è±¡çsynchronizedæ¹æ³æè
synchronized代ç åæ¶ï¼å
¶ä»çº¿ç¨å¯¹`该对象`çésynchronizedæ¹æ³ç访é®å°ä¸ä¼è¢«é»å¡ã
3. å½ä¸ä¸ªçº¿ç¨è®¿é®ä¸ä¸ªå¯¹è±¡çsynchronizedæ¹æ³æè
synchronized代ç åæ¶ï¼å
¶ä»çº¿ç¨å¯¹`该对象`çå
¶ä»synchronizedæ¹æ³æä»£ç åç访é®å°ä¼è¢«é»å¡ã
> synchronizedåºå±åç
* 忥代ç åï¼ä»£ç åç¼è¯åå¨ä»£ç åçåé¢ä¼å ä¸monitorenterï¼å¨ä»£ç åçæåå ä¸monitorexitã
```java
public class SynchronizedDemo {
public void method() {
synchronized (this) {
System.out.println("Method 1 start");
}
}
}
```

æ¯ä¸ªå¯¹è±¡æä¸ä¸ªçè§å¨é(monitor)ãå½monitor被å ç¨æ¶å°±ä¼å¤äºéå®ç¶æï¼çº¿ç¨æ§è¡monitorenteræä»¤æ¶å°è¯è·åmonitorçæææï¼è¿ç¨ï¼
1. 妿monitorçè¿å
¥æ°ä¸º0ï¼å该线ç¨è¿å
¥monitorï¼ç¶åå°è¿å
¥æ°è®¾ç½®ä¸º1ï¼è¯¥çº¿ç¨å³ä¸ºmonitorçææè
ã
2. å¦æçº¿ç¨å·²ç»å æè¯¥monitorï¼åªæ¯éæ°è¿å
¥ï¼åè¿å
¥monitorçè¿å
¥æ°å 1ã
3. 妿å
¶ä»çº¿ç¨å·²ç»å ç¨äºmonitorï¼å该线ç¨è¿å
¥é»å¡ç¶æï¼ç´å°monitorçè¿å
¥æ°ä¸º0ï¼åéæ°å°è¯è·åmonitorçæææã
æ§è¡monitorexitç线ç¨å¿
é¡»æ¯objectrefæå¯¹åºçmonitorçææè
ã
æä»¤æ§è¡æ¶ï¼monitorçè¿å
¥æ°å1ï¼å¦æå1åè¿å
¥æ°ä¸º0ï¼é£çº¿ç¨éåºmonitorï¼ä¸åæ¯è¿ä¸ªmonitorçææè
ãå
¶ä»è¢«è¿ä¸ªmonitoré»å¡ç线ç¨å¯ä»¥å°è¯å»è·åè¿ä¸ª monitor çæææã
éè¿è¿ä¸¤æ®µæè¿°ï¼æä»¬åºè¯¥è½å¾æ¸
æ¥ççåºSynchronizedçå®ç°åçï¼Synchronizedçè¯ä¹åºå±æ¯éè¿ä¸ä¸ªmonitorç对象æ¥å®æï¼å
¶å®wait/notifyçæ¹æ³ä¹ä¾èµäºmonitor对象ï¼è¿å°±æ¯ä¸ºä»ä¹åªæå¨åæ¥çåæè
æ¹æ³ä¸æè½è°ç¨wait/notifyçæ¹æ³ï¼å¦å伿åºjava.lang.IllegalMonitorStateExceptionçå¼å¸¸çåå ã
* åæ¥æ¹æ³ï¼
```java
public class SynchronizedMethod {
public synchronized void method() {
System.out.println("Hello World!");
}
}
```

ä»åç¼è¯çç»ææ¥çï¼æ¹æ³çåæ¥å¹¶æ²¡æéè¿æä»¤monitorenteråmonitorexitæ¥å®æ(ç论ä¸å
¶å®ä¹å¯ä»¥éè¿è¿ä¸¤æ¡æä»¤æ¥å®ç°)ï¼ä¸è¿ç¸å¯¹äºæ®éæ¹æ³ï¼å
¶å¸¸éæ± ä¸å¤äºACC_SYNCHRONIZEDæ 示符ãJVMå°±æ¯æ ¹æ®è¯¥æ 示符æ¥å®ç°æ¹æ³ç忥çï¼å½æ¹æ³è°ç¨æ¶ï¼è°ç¨æä»¤å°ä¼æ£æ¥æ¹æ³ç ACC_SYNCHRONIZED è®¿é®æ å¿æ¯å¦è¢«è®¾ç½®ï¼å¦æè®¾ç½®äºï¼æ§è¡çº¿ç¨å°å
è·åmonitorï¼è·åæåä¹åæè½æ§è¡æ¹æ³ä½ï¼æ¹æ³æ§è¡å®ååéæ¾monitorã卿¹æ³æ§è¡æé´ï¼å
¶ä»ä»»ä½çº¿ç¨é½æ æ³åè·å¾åä¸ä¸ªmonitor对象ã å
¶å®æ¬è´¨ä¸æ²¡æåºå«ï¼åªæ¯æ¹æ³ç忥æ¯ä¸ç§éå¼çæ¹å¼æ¥å®ç°ï¼æ ééè¿åèç æ¥å®æã
### å®ä¾éä¸å
¨å±é
> å®ä¾éï¼é卿ä¸ä¸ªå®ä¾å¯¹è±¡ä¸ãå¦æè¯¥ç±»æ¯åä¾ï¼é£ä¹è¯¥éä¹å
·æå
¨å±éçæ¦å¿µãå®ä¾é对åºçå°±æ¯synchronizedå
³é®åã
```java
synchronized(this) synchronized(obj)
public synchronized void foo()
```
> å
¨å±éï¼è¯¥ééå¯¹çæ¯ç±»ï¼æ 论å®ä¾å¤å°ä¸ªå¯¹è±¡ï¼é£ä¹çº¿ç¨é½å
±äº«è¯¥éãå
¨å±é对åºçå°±æ¯static synchronizedï¼æè
æ¯éå¨è¯¥ç±»çclassæè
classloader对象ä¸ï¼ã
```java
synchronized(XXXClass.class)
public static synchronized void foo()
```
> ä¾å
```java
pulbic class Something {
public synchronized void isSyncA(){}
public synchronized void isSyncB(){}
public static synchronized void cSyncA(){}
public static synchronized void cSyncB(){}
}
```
å设ï¼Somethingæä¸¤ä¸ªå®ä¾xåyãåæä¸é¢4ç»è¡¨è¾¾å¼è·åçéçæ
åµã
1. x.isSyncA()ä¸x.isSyncB() ä¸è½åæ¶è®¿é®ãå®ä¾éï¼è®¿é®ä¸¤ä¸ªåæ¥æ¹æ³ç对象æ¯åä¸ä¸ªå¯¹è±¡x
2. x.isSyncA()ä¸y.isSyncA() è½åæ¶è®¿é®ãå®ä¾éï¼è®¿é®åä¸ä¸ªåæ¥æ¹æ³ç对象æ¯ä¸¤ä¸ªä¸åç对象ï¼å®ä¾é䏿¯åä¸ä¸ª
3. x.cSyncA()ä¸y.cSyncB() ä¸è½åæ¶è®¿é®ãå 为cSyncA()åcSyncB()齿¯staticç±»åï¼x.cSyncA()ç¸å½äºSomething.isSyncA()ï¼y.cSyncB()ç¸å½äºSomething.isSyncB()ï¼å æ¤å®ä»¬å
±ç¨ä¸ä¸ªåæ¥éï¼ä¸è½è¢«åæ¶åé®ã
4. x.isSyncA()ä¸Something.cSyncA() å¯ä»¥è¢«åæ¶è®¿é®ãå 为isSyncA()æ¯å®ä¾æ¹æ³ï¼x.isSyncA()使ç¨çæ¯å¯¹è±¡xçéï¼ècSyncA()æ¯éææ¹æ³ï¼Something.cSyncA()å¯ä»¥ç解对使ç¨çæ¯âç±»çéâãå æ¤ï¼å®ä»¬æ¯å¯ä»¥è¢«åæ¶è®¿é®çã
```java
public class SynchronizedLockExample {
public static void main(String[] args) {
SynchronizedLock x = new SynchronizedLock();
// x.syncA()ä¸x.syncB()
new Thread(()-> {
try {
x.syncA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Threadx ").start();
new Thread(()-> {
try {
x.syncB();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Thready ").start();
/** å®ä¾éãä¸è½åæ¶è®¿é®
* Threadx 0
* Threadx 1
* Threadx 2
* Thready 0
* Thready 1
* Thready 2
*/
// x.syncA()ä¸y.syncA()
SynchronizedLock y = new SynchronizedLock();
SynchronizedLock y2 = new SynchronizedLock();
new Thread(() -> {
try {
y.syncA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Thready1").start();
new Thread(() -> {
try {
y2.syncA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Thready2").start();
/**å®ä¾éãå¯ä»¥åæ¶è®¿é®ï¼å®ä¾ä¸æ¯åä¸ä¸ªå¯¹è±¡é
* Thready10
* Thready20
* Thready21
* Thready11
* Thready22
* Thready12
*/
// x.syncC()ä¸y.syncD()
SynchronizedLock x1 = new SynchronizedLock();
SynchronizedLock y3 = new SynchronizedLock();
new Thread(()-> {
try {
x1.syncC();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Threadx1 ").start();
new Thread(()-> {
try {
y3.syncD();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Thready3 ").start();
/** å
¨å±éãä¸è½åæ¶è®¿é®ï¼static synchronizedä¿®é¥°çæ¹æ³æ¯å
¨å±éæçï¼ä¸å®ä¾æ å
³
* Threadx1 0
* Threadx1 1
* Threadx1 2
* Thready3 0
* Thready3 1
* Thready3 2
*/
// x.syncAä¸SynchronizedLock.syncD
SynchronizedLock x3 = new SynchronizedLock();
new Thread(()-> {
try {
x3.syncA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Theradx3").start();
new Thread(() -> {
try {
SynchronizedLock.syncD();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Threadstatic ").start();
/** å¯ä»¥åæ¶è®¿é®ãx.syncAæ¯å®ä¾éï¼SynchronizedLock.syncDæ¯å
¨å±é
* Theradx30
* Threadstatic 0
* Theradx31
* Threadstatic 1
* Theradx32
* Threadstatic 2
*/
}
}
class SynchronizedLock {
public synchronized void syncA() throws InterruptedException {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + i);
Thread.sleep(1000);
}
}
public synchronized void syncB() throws InterruptedException {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + i);
Thread.sleep(1000);
}
}
public static synchronized void syncC() throws InterruptedException {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + i);
Thread.sleep(1000);
}
}
public static synchronized void syncD() throws InterruptedException {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + i);
Thread.sleep(1000);
}
}
}
```
### waitånotify
> wait, notify, notifyAll
å¨Object.javaä¸ï¼å®ä¹äºwait(), notify()ånotifyAll()çæ¥å£ãwait()çä½ç¨æ¯è®©å½å线ç¨è¿å
¥çå¾
ç¶æï¼åæ¶ï¼wait()ä¹ä¼è®©å½å线ç¨éæ¾å®æææçéãènotify()ånotifyAll()çä½ç¨ï¼åæ¯å¤éå½å对象ä¸ççå¾
线ç¨ï¼notify()æ¯å¤éå个线ç¨ï¼ènotifyAll()æ¯å¤éææç线ç¨ã
Objectç±»ä¸å
³äºçå¾
/å¤éçAPI详ç»ä¿¡æ¯å¦ä¸ï¼
* notify() -- å¤é卿¤å¯¹è±¡çè§å¨ä¸çå¾
çå个线ç¨ã
* notifyAll() -- å¤é卿¤å¯¹è±¡çè§å¨ä¸çå¾
çææçº¿ç¨ã
* wait() -- 让å½å线ç¨å¤äºâçå¾
(é»å¡)ç¶æâï¼âç´å°å
¶ä»çº¿ç¨è°ç¨æ¤å¯¹è±¡ç notify() æ¹æ³æ notifyAll() æ¹æ³âï¼å½å线ç¨è¢«å¤é(è¿å
¥âå°±ç»ªç¶æâ)ã
* wait(long timeout) -- 让å½å线ç¨å¤äºâçå¾
(é»å¡)ç¶æâï¼âç´å°å
¶ä»çº¿ç¨è°ç¨æ¤å¯¹è±¡ç notify() æ¹æ³æ notifyAll() æ¹æ³ï¼æè
è¶
è¿æå®çæ¶é´éâï¼å½å线ç¨è¢«å¤é(è¿å
¥âå°±ç»ªç¶æâ)ã
* wait(long timeout, int nanos) -- 让å½å线ç¨å¤äºâçå¾
(é»å¡)ç¶æâï¼âç´å°å
¶ä»çº¿ç¨è°ç¨æ¤å¯¹è±¡ç notify() æ¹æ³æ notifyAll() æ¹æ³ï¼æè
å
¶ä»æä¸ªçº¿ç¨ä¸æå½å线ç¨ï¼æè
å·²è¶
è¿æä¸ªå®é
æ¶é´éâï¼å½å线ç¨è¢«å¤é(è¿å
¥âå°±ç»ªç¶æâ)ã
```java
public class NotifyExample {
public static void main(String[] args) {
Notify notify = new Notify();
new Thread(()-> {
synchronized (notify) {
while (notify.flag) {
System.out.println("User A");
try {
notify.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
notify.call();
synchronized (notify) {
notify.notifyAll();
}
}, "User A").start();
new Thread(()-> {
synchronized (notify) {
while (notify.flag) {
System.out.println("User B");
try {
notify.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
notify.call();
synchronized (notify) {
notify.notifyAll();
}
}, "User B").start();
/**
* Begin to call
* User A calling 0%
* User B
* User A calling 50%
* User A calling 100%
* End to call
* Begin to call
* User B calling 0%
* User B calling 50%
* User B calling 100%
* End to call
*/
}
}
class Notify {
public boolean flag = false;
public void call() {
flag = true;
System.out.println("Begin to call");
for (int i = 0; i < 101; i+=50) {
System.out.println(Thread.currentThread().getName() + " calling " + i + "%");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("End to call");
flag = false;
}
}
```
> 注æäºé¡¹
* âå½å线ç¨âå¨è°ç¨wait()æ¶ï¼å¿
é¡»æ¥æè¯¥å¯¹è±¡ç忥éã该线ç¨è°ç¨wait()ä¹åï¼ä¼éæ¾è¯¥éï¼ç¶åä¸ç´çå¾
ç´å°âå
¶å®çº¿ç¨âè°ç¨å¯¹è±¡ç忥éçnotify()ænotifyAll()æ¹æ³ãç¶åï¼è¯¥çº¿ç¨ç»§ç»çå¾
ç´å°å®éæ°è·åâ该对象ç忥éâï¼ç¶åå°±å¯ä»¥æ¥çè¿è¡ã, synchronized(obj)ï¼å¦åä¼åºç°`java.lang.IllegalMonitorStateException`
* è°ç¨notifyæ¶ä¹éè¦è·å¾è¯¥å¯¹è±¡çâ忥éâï¼jdkä¸ç注éï¼
```md
This method should only be called by a thread that is the owner of this object's monitor. A thread becomes the owner of the object's monitor in one of three ways:
1. By executing a synchronized instance method of that object. éè¿è·å¾è¯¥å¯¹è±¡ç忥é
2. By executing the body of a {@code synchronized} statement that synchronizes on the object. å¨è¯¥å¯¹è±¡ç忥代ç å䏿§è¡
3. For objects of type {@code Class,} by executing a synchronized static method of that class. éè¿æ§è¡å
¨å±éçæ¹æ³
```
* Only one thread at a time can own an object's monitor.
> 为ä»ä¹notify(), wait()ç彿°å®ä¹å¨Objectä¸ï¼è䏿¯Threadä¸
Objectä¸çwait(), notify()ç彿°ï¼åsynchronized䏿 ·ï¼ä¼å¯¹â对象ç忥éâè¿è¡æä½ã
wait()ä¼ä½¿âå½å线ç¨âçå¾
ï¼å 为线ç¨è¿å
¥çå¾
ç¶æï¼æä»¥çº¿ç¨åºè¯¥éæ¾å®éææçâ忥éâï¼å¦åå
¶å®çº¿ç¨è·åä¸å°è¯¥â忥éâèæ æ³è¿è¡ï¼
OKï¼çº¿ç¨è°ç¨wait()ä¹åï¼ä¼éæ¾å®éææçâ忥éâï¼èä¸ï¼æ ¹æ®åé¢çä»ç»ï¼æä»¬ç¥éï¼çå¾
线ç¨å¯ä»¥è¢«notify()ænotifyAll()å¤éãç°å¨ï¼è¯·æèä¸ä¸ªé®é¢ï¼notify()æ¯ä¾æ®ä»ä¹å¤éçå¾
线ç¨çï¼æè
说ï¼wait()çå¾
线ç¨ånotify()ä¹é´æ¯éè¿ä»ä¹å
³èèµ·æ¥çï¼çæ¡æ¯ï¼ä¾æ®â对象ç忥éâã
è´è´£å¤éçå¾
线ç¨çé£ä¸ªçº¿ç¨(æä»¬ç§°ä¸ºâå¤é线ç¨â)ï¼å®åªæå¨è·åâ该对象ç忥éâ(è¿éç忥éå¿
é¡»åçå¾
线ç¨ç忥鿝åä¸ä¸ª)ï¼å¹¶ä¸è°ç¨notify()ænotifyAll()æ¹æ³ä¹åï¼æè½å¤éçå¾
线ç¨ãè½ç¶ï¼çå¾
线ç¨è¢«å¤éï¼ä½æ¯ï¼å®ä¸è½ç«å»æ§è¡ï¼å 为å¤é线ç¨è¿ææâ该对象ç忥éâãå¿
é¡»çå°å¤é线ç¨éæ¾äºâ对象ç忥éâä¹åï¼çå¾
çº¿ç¨æè½è·åå°â对象ç忥éâè¿èç»§ç»è¿è¡ã
æ»ä¹ï¼notify(), wait()ä¾èµäºâ忥éâï¼èâ忥éâæ¯å¯¹è±¡éææï¼å¹¶ä¸æ¯ä¸ªå¯¹è±¡æä¸ä»
æä¸ä¸ªï¼è¿å°±æ¯ä¸ºä»ä¹notify(), wait()ç彿°å®ä¹å¨Objectç±»ï¼è䏿¯Threadç±»ä¸çåå ã
### 线ç¨ç让æ¥yeild
* Yieldæ¯ä¸ä¸ªéæçåç(native)æ¹æ³
* Yieldåè¯å½åæ£å¨æ§è¡ççº¿ç¨æè¿è¡æºä¼äº¤ç»çº¿ç¨æ± 䏿¥æç¸åä¼å
级ç线ç¨ã
* Yieldä¸è½ä¿è¯ä½¿å¾å½åæ£å¨è¿è¡ç线ç¨è¿
é转æ¢å°å¯è¿è¡çç¶æï¼å®ä»
è½ä½¿ä¸ä¸ªçº¿ç¨ä»è¿è¡ç¶æè½¬å°å¯è¿è¡ç¶æï¼è䏿¯çå¾
æé»å¡ç¶æ
```java
public class YieldExample {
public static void main(String[] args) {
Yeild yeild = new Yeild();
new Thread(yeild::call, "yeild1 ").start();
new Thread(yeild::call, "yeild2 ").start();
new Thread(yeild::call, "yeild3 ").start();
new Thread(yeild::call, "yeild4 ").start();
new Thread(yeild::call, "yeild5 ").start();
new Thread(yeild::call, "yeild6 ").start();
new Thread(yeild::call, "yeild7 ").start();
new Thread(yeild::call, "yeild8 ").start();
new Thread(yeild::call, "yeild9 ").start();
new Thread(yeild::call, "yeild0 ").start();
}
}
class Yeild {
public synchronized void call() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + i);
if(i % 4 == 0) {
Thread.yield();
}
}
}
}
```
> yeildåwaitçåºå«
wait()çä½ç¨æ¯è®©å½å线ç¨ç±âè¿è¡ç¶æâè¿å
¥âçå¾
(é»å¡)ç¶æâçåæ¶ï¼ä¹ä¼éæ¾åæ¥éãèyield()çä½ç¨æ¯è®©æ¥ï¼å®ä¹ä¼è®©å½å线ç¨ç¦»å¼âè¿è¡ç¶æâãå®ä»¬çåºå«æ¯ï¼
1. wait()æ¯è®©çº¿ç¨ç±âè¿è¡ç¶æâè¿å
¥å°âçå¾
(é»å¡)ç¶æâï¼èyield()æ¯è®©çº¿ç¨ç±âè¿è¡ç¶æâè¿å
¥å°âå°±ç»ªç¶æâã
2. wait()æ¯ä¼çº¿ç¨éæ¾å®æææå¯¹è±¡ç忥éï¼èyield()æ¹æ³ä¸ä¼éæ¾éã
### 线ç¨çä¼ç sleep
sleep() å®ä¹å¨Thread.javaä¸ã
sleep() çä½ç¨æ¯è®©å½å线ç¨ä¼ç ï¼å³å½å线ç¨ä¼ä»âè¿è¡ç¶æâè¿å
¥å°âä¼ç (é»å¡)ç¶æâãsleep()伿å®ä¼ç æ¶é´ï¼çº¿ç¨ä¼ç çæ¶é´ä¼å¤§äº/çäºè¯¥ä¼ç æ¶é´ï¼å¨çº¿ç¨éæ°è¢«å¤éæ¶ï¼å®ä¼ç±âé»å¡ç¶æâåæâå°±ç»ªç¶æâï¼ä»èçå¾
cpuçè°åº¦æ§è¡ã
> sleep() ä¸ wait()çæ¯è¾
æä»¬ç¥éï¼wait()çä½ç¨æ¯è®©å½å线ç¨ç±âè¿è¡ç¶æâè¿å
¥âçå¾
(é»å¡)ç¶æâçåæ¶ï¼ä¹ä¼éæ¾åæ¥éãèsleep()çä½ç¨æ¯ä¹æ¯è®©å½å线ç¨ç±âè¿è¡ç¶æâè¿å
¥å°âä¼ç (é»å¡)ç¶æâã使¯ï¼wait()ä¼éæ¾å¯¹è±¡ç忥éï¼èsleep()åä¸ä¼éæ¾éã
### Threadä¸çjoin
When we call this method using a thread object, it suspends the execution of the calling thread until the object called finishes its execution.
彿们è°ç¨æä¸ªçº¿ç¨çè¿ä¸ªæ¹æ³æ¶ï¼è¿ä¸ªæ¹æ³ä¼æèµ·è°ç¨çº¿ç¨ï¼ç´å°è¢«è°ç¨çº¿ç¨ç»ææ§è¡ï¼è°ç¨çº¿ç¨æä¼ç»§ç»æ§è¡ã
join() ä¸å
±æä¸ä¸ªéè½½çæ¬ï¼å嫿¯æ åãä¸ä¸ªåæ°ãä¸¤ä¸ªåæ°ï¼
```java
public final void join() throws InterruptedException;
public final synchronized void join(long millis) throws InterruptedException;
public final synchronized void join(long millis, int nanos) throws InterruptedException;
æºç åæ
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);// æ¤å¤è°ç¨waitä¼è®©å½å线ç¨ä»è¿è¡ç¶æå为é»å¡ç¶æï¼å¹¶è®©åºå¯¹è±¡é
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
```
å°ç»
1. ä¸ä¸ªæ¹æ³é½è¢«finalä¿®é¥°ï¼æ æ³è¢«åç±»éåã
2. join(long), join(long, long) æ¯synchronized methodï¼åæ¥ç对象æ¯å½å线ç¨å®ä¾ã
3. æ åçæ¬åä¸¤ä¸ªåæ°çæ¬æç»é½è°ç¨äºä¸ä¸ªåæ°ççæ¬ãjoin() å join(0) æ¯çä»·çï¼è¡¨ç¤ºä¸ç´çä¸å»ï¼join(é0)表示çå¾
䏿®µæ¶é´ã
4. 仿ºç å¯ä»¥çå° join(0) è°ç¨äºObject.wait(0)ï¼å
¶ä¸Object.wait(0) ä¼ä¸ç´çå¾
ï¼ç´å°è¢«notify/䏿æè¿åã
while(isAlive())æ¯ä¸ºäºé²æ¢å线ç¨ä¼ªå¤é(spurious wakeup)ï¼åªè¦åçº¿ç¨æ²¡æTERMINATEDçï¼ç¶çº¿ç¨å°±éè¦ç»§ç»çä¸å»ã
5. join() å sleep() 䏿 ·ï¼å¯ä»¥è¢«ä¸æï¼è¢«ä¸ææ¶ï¼ä¼æåº InterrupptedException å¼å¸¸ï¼ï¼ä¸åçæ¯ï¼join() å
é¨è°ç¨äº wait()ï¼ä¼åºè®©éï¼è sleep() ä¼ä¸ç´ä¿æéã
```java
thread1.start();
thread1.join();
thread2.start();
thread2.join();
thread3.start();
thread3.join();
```
è°ç¨çº¿ç¨çwait()æ¹æ³æ¶ï¼ä¼ä½¿ä¸»çº¿ç¨å¤äºçå¾
ç¶æï¼çå¾
åçº¿ç¨æ§è¡å®æå忬¡å䏿§è¡ãä¹å°±æ¯è¯´ï¼å¨ThreadSort02ç±»çmain()æ¹æ³ä¸ï¼è°ç¨å线ç¨çjoin()æ¹æ³ï¼ä¼é»å¡main()æ¹æ³çæ§è¡ï¼å½åçº¿ç¨æ§è¡å®æåï¼main()æ¹æ³ä¼ç»§ç»å䏿§è¡ï¼å¯å¨ç¬¬äºä¸ªå线ç¨ï¼å¹¶æ§è¡å线ç¨çä¸å¡é»è¾ï¼ä»¥æ¤ç±»æ¨
### 线ç¨ç䏿interrupted
interrupt()çä½ç¨æ¯ä¸ææ¬çº¿ç¨ã
æ¬çº¿ç¨ä¸æèªå·±æ¯è¢«å
许çï¼å
¶å®çº¿ç¨è°ç¨æ¬çº¿ç¨çinterrupt()æ¹æ³æ¶ï¼ä¼éè¿checkAccess()æ£æ¥æéãè¿æå¯è½æåºSecurityExceptionå¼å¸¸ã
* ç»æ¢å¤äºâé»å¡ç¶æâç线ç¨: éè¿âä¸æâæ¹å¼ç»æ¢å¤äºâé»å¡ç¶æâç线ç¨ãå½çº¿ç¨ç±äºè¢«è°ç¨äºsleep(), wait(), join()çæ¹æ³èè¿å
¥é»å¡ç¶æï¼è¥æ¤æ¶è°ç¨çº¿ç¨çinterrupt()å°çº¿ç¨ç䏿æ 记设为trueãç±äºå¤äºé»å¡ç¶æï¼ä¸ææ è®°ä¼è¢«æ¸
é¤ï¼åæ¶äº§çä¸ä¸ªInterruptedExceptionå¼å¸¸ãå°InterruptedExceptionæ¾å¨éå½ç为æ¢å°±è½ç»æ¢çº¿ç¨ã
```java
@Override
public void run() {
while (true) {
try {
// æ§è¡ä»»å¡...
} catch (InterruptedException ie) {
// InterruptedExceptionå¨while(true)循ç¯ä½å
ã
// å½çº¿ç¨äº§çäºInterruptedExceptionå¼å¸¸æ¶ï¼while(true)ä»è½ç»§ç»è¿è¡ï¼éè¦æå¨éåº
break;
}
}
}
}
```
说æï¼å¨while(true)ä¸ä¸æçæ§è¡ä»»å¡ï¼å½çº¿ç¨å¤äºé»å¡ç¶ææ¶ï¼è°ç¨çº¿ç¨çinterrupt()产çInterruptedException䏿ã䏿çæè·å¨while(true)ä¹å¤ï¼è¿æ ·å°±éåºäºwhile(true)循ç¯ï¼
InterruptedExceptionå¼å¸¸çæè·å¨whle(true)ä¹å
ãå½äº§çInterruptedExceptionå¼å¸¸æ¶ï¼è¢«catchå¤çä¹å¤ï¼ä»ç¶å¨while(true)循ç¯ä½å
ï¼è¦éåºwhile(true)循ç¯ä½ï¼éè¦é¢å¤çæ§è¡éåºwhile(true)çæä½ãthreadå¨âçå¾
(é»å¡)ç¶æâæ¶ï¼è¢«interrupt()ä¸æï¼æ¤æ¶ï¼ä¼æ¸
é¤ä¸ææ è®°(å³isInterrupted()ä¼è¿åfalse)ï¼èä¸ä¼æåºInterruptedExceptionå¼å¸¸(该å¼å¸¸å¨while循ç¯ä½å
被æè·)
### 线ç¨çç¶æä¸è½¬æ¢
线ç¨å
±å
æ¬ä»¥ä¸5ç§ç¶æã
1. æ°å»ºç¶æ(New): å建äºçº¿ç¨å¯¹è±¡ä½å°æªè°ç¨start()æ¹æ³æ¶çç¶æã
2. å°±ç»ªç¶æ(Runnable): ä¹è¢«ç§°ä¸ºâ坿§è¡ç¶æâã线ç¨å¯¹è±¡è¢«å建åï¼å
¶å®çº¿ç¨è°ç¨äºè¯¥å¯¹è±¡çstart()æ¹æ³ï¼ä»èæ¥å¯å¨è¯¥çº¿ç¨ãä¾å¦ï¼thread.start()ãå¤äºå°±ç»ªç¶æç线ç¨ï¼éæ¶å¯è½è¢«CPUè°åº¦æ§è¡ã
3. é»å¡ç¶æ(Blocked): é»å¡ç¶ææ¯çº¿ç¨å 为æç§åå æ¾å¼CPUä½¿ç¨æï¼ææ¶åæ¢è¿è¡ãç´å°çº¿ç¨è¿å
¥å°±ç»ªç¶æï¼æææºä¼è½¬å°è¿è¡ç¶æãé»å¡çæ
åµåä¸ç§ï¼
(01) çå¾
é»å¡ -- éè¿è°ç¨çº¿ç¨çwait()æ¹æ³ï¼è®©çº¿ç¨çå¾
æå·¥ä½ç宿ã
(02) 忥é»å¡ -- 线ç¨å¨è·åsynchronized忥é失败(å 为é被å
¶å®çº¿ç¨æå ç¨)ï¼å®ä¼è¿å
¥åæ¥é»å¡ç¶æã
(03) å
¶ä»é»å¡ -- éè¿è°ç¨çº¿ç¨çsleep()æjoin()æååºäºI/Oè¯·æ±æ¶ï¼çº¿ç¨ä¼è¿å
¥å°é»å¡ç¶æãå½sleep()ç¶æè¶
æ¶ãjoin()çå¾
线ç¨ç»æ¢æè
è¶
æ¶ãæè
I/Oå¤ç宿¯æ¶ï¼çº¿ç¨éæ°è½¬å
¥å°±ç»ªç¶æã
4. çå¾
ç¶æ(Waiting)ï¼çº¿ç¨å¤äºçå¾
ç¶æï¼å¤äºè¯¥ç¶ææ è¯çå½å线ç¨éè¦çå¾
å
¶ä»çº¿ç¨ååºä¸äºç¹å®çæä½æ¥å¤éèªå·±ã
5. è¶
æ¶çå¾
ç¶æ(Time Waiting)ï¼è¶
æ¶çå¾
ç¶æï¼ä¸Waitingä¸åï¼å¨çå¾
æå®çæ¶é´åä¼èªè¡è¿åã
6. ç»æ¢ç¶æ(Terminated): çº¿ç¨æ§è¡å®äºæè
å å¼å¸¸éåºäºrun()æ¹æ³ï¼è¯¥çº¿ç¨ç»æçå½å¨æã

> è¡¥å
说æ
* Thread.sleep(long millis)ï¼ä¸å®æ¯å½å线ç¨è°ç¨æ¤æ¹æ³ï¼å½å线ç¨è¿å
¥TIMED_WAITINGç¶æï¼ä½ä¸éæ¾å¯¹è±¡éï¼milliså线ç¨èªå¨èéè¿å
¥å°±ç»ªç¶æãä½ç¨ï¼ç»å
¶å®çº¿ç¨æ§è¡æºä¼çæä½³æ¹å¼ã
* Thread.yield()ï¼ä¸å®æ¯å½å线ç¨è°ç¨æ¤æ¹æ³ï¼å½åçº¿ç¨æ¾å¼è·åçCPUæ¶é´çï¼ä½ä¸éæ¾éèµæºï¼ç±è¿è¡ç¶æåä¸ºå°±ç»ªç¶æï¼è®©OS忬¡éæ©çº¿ç¨ãä½ç¨ï¼è®©ç¸åä¼å
级ç线ç¨è½®æµæ§è¡ï¼ä½å¹¶ä¸ä¿è¯ä¸å®ä¼è½®æµæ§è¡ãå®é
䏿 æ³ä¿è¯yield()è¾¾å°è®©æ¥ç®çï¼å 为让æ¥ç线ç¨è¿æå¯è½è¢«çº¿ç¨è°åº¦ç¨åºå次éä¸ãThread.yield()ä¸ä¼å¯¼è´é»å¡ãè¯¥æ¹æ³ä¸sleep()类似ï¼åªæ¯ä¸è½ç±ç¨æ·æå®æåå¤é¿æ¶é´ã
* t.join()/t.join(long millis)ï¼å½å线ç¨éè°ç¨å
¶å®çº¿ç¨tçjoinæ¹æ³ï¼å½å线ç¨è¿å
¥WAITING/TIMED_WAITINGç¶æï¼å½å线ç¨ä¸ä¼éæ¾å·²ç»ææç对象éã线ç¨tæ§è¡å®æ¯æè
millisæ¶é´å°ï¼å½å线ç¨è¿å
¥å°±ç»ªç¶æã
* obj.wait()ï¼å½å线ç¨è°ç¨å¯¹è±¡çwait()æ¹æ³ï¼å½å线ç¨éæ¾å¯¹è±¡éï¼è¿å
¥çå¾
éåãä¾é notify()/notifyAll()å¤éæè
wait(long timeout) timeoutæ¶é´å°èªå¨å¤éã
* obj.notify()å¤é卿¤å¯¹è±¡çè§å¨ä¸çå¾
çå个线ç¨ï¼éæ©æ¯ä»»ææ§çãnotifyAll()å¤é卿¤å¯¹è±¡çè§å¨ä¸çå¾
çææçº¿ç¨ã
### ç产è
æ¶è´¹è
é®é¢
æè°çç产è
æ¶è´¹è
模åï¼æ¯éè¿ä¸ä¸ªå®¹å¨æ¥è§£å³ç产è
åæ¶è´¹è
ç强è¦åé®é¢ãéä¿ç讲ï¼å°±æ¯ç产è
å¨ä¸æççäº§ï¼æ¶è´¹è
ä¹å¨ä¸æçæ¶è´¹ï¼å¯æ¯æ¶è´¹è
æ¶è´¹çäº§åæ¯ç产è
ç产çï¼è¿å°±å¿
ç¶åå¨ä¸ä¸ªä¸é´å®¹å¨ï¼æä»¬å¯ä»¥æè¿ä¸ªå®¹å¨æ³è±¡ææ¯ä¸ä¸ªè´§æ¶ï¼å½è´§æ¶ç©ºçæ¶åï¼ç产è
è¦ç产产åï¼æ¤æ¶æ¶è´¹è
å¨çå¾
ç产è
å¾è´§æ¶ä¸ç产产åï¼èå½è´§æ¶æ»¡çæ¶åï¼æ¶è´¹è
å¯ä»¥ä»è´§æ¶ä¸æ¿èµ°ååï¼ç产è
æ¤æ¶çå¾
è´§æ¶ç空ä½ï¼è¿æ ·ä¸æç循ç¯ãé£ä¹å¨è¿ä¸ªè¿ç¨ä¸ï¼ç产è
åæ¶è´¹è
æ¯ä¸ç´æ¥æ¥è§¦çï¼æè°çâè´§æ¶âå
¶å®å°±æ¯ä¸ä¸ªé»å¡éåï¼ç产è
ç产ç产åä¸ç´æ¥ç»æ¶è´¹è
æ¶è´¹ï¼èæ¯ä»ç»é»å¡éåï¼è¿ä¸ªé»å¡éåå°±æ¯æ¥è§£å³ç产è
æ¶è´¹è
ç强è¦åçãå°±æ¯ç产è
æ¶è´¹è
模åã
```java
public class Product {
private int size;
private final int capactiy = 100;
public synchronized void product(int n) {
while(size >= capactiy) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
size+=n;
System.out.println(Thread.currentThread().getName() + "ç产" + n + "个ï¼å©ä½" + size);
notifyAll();
}
public synchronized void consume(int n) {
while ((size - n) < 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
size-=n;
System.out.println(Thread.currentThread().getName() + "æ¶è´¹" + n + "个ï¼å©ä½" + size);
notifyAll();
}
}
```
### é©å线ç¨
å¨çº¿ä¸Javaç¨åºä¸ç»å¸¸éå°è¿ç¨ç¨ææï¼ä¸äºç¶ææ²¡ææ£ç¡®çä¿å䏿¥ï¼è¿æ¶åå°±éè¦å¨JVMå
³æçæ¶åæ§è¡ä¸äºæ¸
çç°åºç代ç ãJavaä¸å¾ShutdownHookæä¾äºæ¯è¾å¥½çæ¹æ¡ã
JDKå¨1.3ä¹åæä¾äºJava Runtime.addShutdownHook(Thread hook)æ¹æ³ï¼å¯ä»¥æ³¨åä¸ä¸ªJVMå
³éçé©åï¼è¿ä¸ªé©åå¯ä»¥å¨ä»¥ä¸å ç§åºæ¯è¢«è°ç¨ï¼
1. ç¨åºæ£å¸¸éåº
2. 使ç¨System.exit()
3. ç»ç«¯ä½¿ç¨Ctrl+C触åç䏿
4. ç³»ç»å
³é
5. 使ç¨Kill pidå½ä»¤å¹²æè¿ç¨
注ï¼å¨ä½¿ç¨kill -9 pidæ¯ä¸ä¼JVM注åçé©åä¸ä¼è¢«è°ç¨ã
å¨JDK䏿¹æ³ç声æï¼
public void addShutdownHook(Thread hook) åæ° hook â ä¸ä¸ªåå§åä½å°æªå¯å¨ç线ç¨å¯¹è±¡ï¼æ³¨åå°JVMé©åçè¿è¡ä»£ç ã
```java
public static void main(String[] args) throws InterruptedException {
System.out.println("Begin to run");
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hook");
}
}));
Scanner scanner = new Scanner(System.in);
// æCtrl + xä¼è°ç¨hook threadï¼idea䏿äºctrl+d
System.out.println(scanner.next());
Thread.sleep(10000);
// æ§è¡ç³»ç»æ¨åºä¼è°ç¨hook thread
System.exit(0);
System.out.println("End to run");
// ç³»ç»æ£å¸¸éåºä¼è°ç¨hook thread
/**
* egin to run
* ^D
* Hook
* Exception in thread "main" java.util.NoSuchElementException
* at java.util.Scanner.throwFor(Scanner.java:862)
* at java.util.Scanner.next(Scanner.java:1371)
* at com.zhonghuasheng.basic.java.thread.hook.HookThreadExample.main(HookThreadExample.java:16)
* ^D
*/
}
}
```
### 线ç¨ä¸çå¼å¸¸
å¼å¸¸å为checked exceptionåunchecked exceptionã
* checked exception: å¨çº¿ç¨ä¸éå°checked exceptionï¼æä»¬å¯ä»¥ç´æ¥catchä½ï¼ç¶åå¤çã
* unchecked exception: å¯ä»¥éè¿thread.setUncaughtExceptionHandleræ¥æè·
```java
public class UncaughtExceptionExample {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 2; i > -1 ; i--) {
System.out.println(10 / i);
}
}
}, "ThreadA ");
thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Caught exception in thread " + t.getName());
System.out.println("Exception is " + e.getMessage());
}
});
thread.start();
/**ç´æ¥è¿è¡çç»æ
* 5
* Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
* 10
* at com.zhonghuasheng.basic.java.thread.exception.UncaughtExceptionExample$1.run(UncaughtExceptionExample.java:10)
* at java.lang.Thread.run(Thread.java:745)
** å äºUncaughtExceptionHandlerè¿è¡çç»æ
* 5
* 10
* Caught exception in thread ThreadA
* Exception is / by zero
*
* Process finished with exit code 0
*/
}
}
```
æ ¸å¿çº¿ç¨ï¼corePoolï¼ï¼çº¿ç¨æ± æç»æ§è¡ä»»å¡çè§è²è¯å®è¿æ¯çº¿ç¨ï¼åæ¶æä»¬ä¹ä¼éå¶çº¿ç¨çæ°éï¼æä»¥æä»¬å¯ä»¥è¿æ ·çè§£æ ¸å¿çº¿ç¨ï¼ææ°ä»»å¡æäº¤æ¶ï¼é¦å
æ£æ¥æ ¸å¿çº¿ç¨æ°ï¼å¦ææ ¸å¿çº¿ç¨é½å¨å·¥ä½ï¼è䏿°éä¹å·²ç»è¾¾å°æå¤§æ ¸å¿çº¿ç¨æ°ï¼åä¸ä¼ç»§ç»æ°å»ºæ ¸å¿çº¿ç¨ï¼èä¼å°ä»»å¡æ¾å
¥çå¾
éåã
çå¾
éå (workQueue)ï¼çå¾
éåç¨äºåå¨å½æ ¸å¿çº¿ç¨é½å¨å¿æ¶ï¼ç»§ç»æ°å¢çä»»å¡ï¼æ ¸å¿çº¿ç¨å¨æ§è¡å®å½åä»»å¡åï¼ä¹ä¼å»çå¾
éåæåä»»å¡ç»§ç»æ§è¡ï¼è¿ä¸ªéåä¸è¬æ¯ä¸ä¸ªçº¿ç¨å®å
¨çé»å¡éåï¼å®ç容éä¹å¯ä»¥ç±å¼åè
æ ¹æ®ä¸å¡æ¥å®å¶ã
éæ ¸å¿çº¿ç¨ï¼å½çå¾
éåæ»¡äºï¼å¦æå½åçº¿ç¨æ°æ²¡æè¶
è¿æå¤§çº¿ç¨æ°ï¼å伿°å»ºçº¿ç¨æ§è¡ä»»å¡ï¼é£ä¹æ ¸å¿çº¿ç¨åéæ ¸å¿çº¿ç¨å°åºæä»ä¹åºå«å¢ï¼è¯´åºæ¥ä½ å¯è½ä¸ä¿¡ï¼æ¬è´¨ä¸å®ä»¬æ²¡æä»ä¹åºå«ï¼åå»ºåºæ¥ç线ç¨ä¹æ ¹æ¬æ²¡ææ è¯å»åºåå®ä»¬æ¯æ ¸å¿è¿æ¯éæ ¸å¿çï¼çº¿ç¨æ± åªä¼å»å¤æå·²æççº¿ç¨æ°ï¼å
æ¬æ ¸å¿åéæ ¸å¿ï¼å»è·æ ¸å¿çº¿ç¨æ°åæå¤§çº¿ç¨æ°æ¯è¾ï¼æ¥å³å®ä¸ä¸æ¥ççç¥ã
### çº¿ç¨æ±
Executoræ¡æ¶æ¯æjava5ä¸å¼å
¥çä¸ç³»åå¹¶ååºä¸ä¸executorç¸å
³çä¸äºåè½ç±»ï¼å
¶ä¸å
æ¬çº¿ç¨æ± ï¼Executorï¼Executorsï¼ExecutorServiceï¼
CompletionServiceï¼Futureï¼Callableçãå¹¶åç¼ç¨çä¸ç§ç¼ç¨æ¹å¼æ¯æä»»å¡æå为ä¸äºåçå°ä»»å¡ï¼å³Runnableï¼ç¶åå¨æäº¤ç»ä¸ä¸ªExecutoræ§è¡ï¼Executor.execute(Runnalbe)ãExecutor卿§è¡æ¶ä½¿ç¨å
é¨ççº¿ç¨æ± 宿æä½ã

#### åå»ºçº¿ç¨æ± 常ç¨çç±»
* Executors.newCachedThreadPool: å建ä¸ä¸ªå¯ç¼åççº¿ç¨æ±
* Executors.newFixedThreadPool: å建ä¸ä¸ªå®é¿ççº¿ç¨æ± ï¼å¯ä»¥æ§å¶çº¿ç¨çæå¤§å¹¶åæ°ï¼è¶
åºç线ç¨ä¼å¨éåä¸çå¾
* Executors.newScheduledThreadPool: å建ä¸ä¸ªå®é¿ççº¿ç¨æ± ï¼æ¯æå®æ¶ã卿æ§ç任塿§è¡
* Executors.newSingleThreadExecutor: å建ä¸ä¸ªå线ç¨ççº¿ç¨æ± ï¼ä½¿ç¨ä¸ä¸ªå¯ä¸çå·¥ä½çº¿ç¨æ§è¡ä»»å¡ï¼ä¿è¯ææä»»å¡æç
§æå®é¡ºåºæ§è¡
* Executors.newSingleThreadScheduledExecutor: å建ä¸ä¸ªå线ç¨ççº¿ç¨æ± ï¼æ¯æå®æ¶ã卿æ§ç任塿§è¡
* Executors.newWorkStealingPool: å建ä¸ä¸ªå
·æå¹¶è¡çº§å«çwork-stealingçº¿ç¨æ±
> åæ°
* corePoolSize: æ ¸å¿çº¿ç¨æ°é
* maximumPoolSize: æå¤§çº¿ç¨æ°
* workQueue: é»å¡éåï¼åå¨çå¾
æ§è¡çä»»å¡
çº¿ç¨æ± 任塿§è¡ç主è¦å·¥ä½æµç¨ï¼
1. 妿è¿è¡ççº¿ç¨æ°å°äºcorePoolSizeï¼ç´æ¥å建æ°çº¿ç¨å¤çä»»å¡ï¼å³ä½¿çº¿ç¨æ± ä¸çå
¶ä»çº¿ç¨æ¯ç©ºé²ç
2. 妿è¿è¡ççº¿ç¨æ°å¤§äºçäºcordPoolSizeï¼å¹¶ä¸å°äºmaximumPoolSizeï¼åå°æ¤ä»»å¡æ¾å
¥éåworkQueueï¼å¦æworkQueueæ»¡å¹¶ä¸æ£å¨è¿è¡ççº¿ç¨æ°éå°äºmaximumPoolSizeï¼æä¼å建æ°çéæ ¸å¿çº¿ç¨å¤çä»»å¡
3. 妿è¿è¡ççº¿ç¨æ°é大äºçäºmaximumPoolSizeï¼åæ¶ï¼workQueueå·²ç»æ»¡äºï¼ä¼éè¿æç»çç¥åæ°rejectHandleræ¥æå®å¤ççç¥
4. å½ä¸ä¸ªçº¿ç¨å®æä»»å¡æ¶ï¼å®ä¼ä»éåä¸åä¸ä¸ä¸ªä»»å¡æ¥æ§è¡ã
5. å½ä¸ä¸ªçº¿ç¨ç©ºé²æ¶ï¼è¶
è¿ä¸å®çæ¶é´(keepAliveTime)æ¶ï¼çº¿ç¨æ± ä¼å¤æï¼å¦æå½åè¿è¡ççº¿ç¨æ°å¤§äº corePoolSize å¼ï¼é£ä¹è¿ä¸ªçº¿ç¨ä¼è¢«éæ¯ã
> æ ¹æ®ä¸é¢ä¸ä¸ªåæ°é
ç½®ï¼çº¿ç¨æ± ä¼å¯¹ä»»å¡è¿è¡å¦ä¸å¤çæ¹å¼
```
å½æäº¤ä¸ä¸ªæ°çä»»å¡å°çº¿ç¨æ± ï¼çº¿ç¨æ± 伿 ¹æ®å½åçº¿ç¨æ± 䏿£å¨è¿è¡ççº¿ç¨æ°éæ¥å³å®è¯¥ä»»å¡çå¤çæ¹å¼ï¼å¤çæ¹å¼å
±æä¸ç§ï¼ç´æ¥åæ¢ãä½¿ç¨æ ééåãä½¿ç¨æçéå
1. ç´æ¥åæ¢å¸¸ç¨çéåå°±æ¯SynchronousQueue
2. ä½¿ç¨æ ééåå°±æ¯ä½¿ç¨åºäºé¾è¡¨çéåï¼æ¯å¦ï¼LinkedBlockingQueueï¼å¦æä½¿ç¨è¿ç§æ¹å¼ï¼çº¿ç¨æ± ä¸å建çæå¤§çº¿ç¨å°±æ¯corePoolSizeï¼æ¤æ¶maximumPoolSizeä¸ä¼èµ·ä½ç¨ï¼å 为é忝æ éçï¼workQueueä¸ä¼æ»¡ãå½çº¿ç¨æ± ä¸çææçæ ¸å¿çº¿ç¨é½æ¯è¿è¡ç¶ææ¶ï¼æäº¤æ°ä»»å¡ï¼å°±ä¼æ¾å
¥çå¾
éåä¸
3. ä½¿ç¨æçé忝å¦ArrayBlockingQueueï¼ä½¿ç¨è¿ç§æ¹å¼å¯ä»¥å°çº¿ç¨æ± çæå¤§çº¿ç¨æ°éå¶ä¸ºmaximumPoolSizeï¼å¯ä»¥éä½èµæºçæ¶èã
```
> åæ°
* keepAliveTime: çº¿ç¨æ²¡æä»»å¡æ§è¡æ¶æå¤ä¿æå¤ä¹
æ¶é´ç»æ¢
* unit: keepAliveTimeçæ¶é´åä½
* threadFactory: 线ç¨å·¥åï¼ç¨æ¥å建线ç¨
* rejectHandler: æç»å¤ç任塿¶ççç¥
```
妿workQueueé»å¡éåæ»¡äºï¼å¹¶ä¸æ²¡æç©ºé²ççº¿ç¨æ± ï¼æ¤æ¶ï¼ç»§ç»æäº¤ä»»å¡ï¼éè¦éåä¸ç§çç¥æ¥å¤çè¿ä¸ªä»»å¡
1. é»è®¤ç´æ¥æåºå¼å¸¸ï¼å®ç°ç±»ä¸ºAbortPolicy
2. ç¨è°ç¨è
æå¨ççº¿ç¨æ¥æ§è¡ä»»å¡ï¼å®ç°ç±»ä¸ºCallerRunsPolicy
3. 丢å¼éå䏿é åçä»»å¡ï¼å¹¶æ§è¡å½åä»»å¡ï¼å®ç°ç±»DiscardOldestPolicy
4. ç´æ¥ä¸¢å¼å½åä»»å¡ï¼å®ç°ç±»ä¸ºDiscardPolicy
```
> ThreadPoolExecutoræä¾çå¯å¨å忢任å¡çæ¹æ³
1. execute(); æäº¤ä»»å¡ï¼äº¤ç»çº¿ç¨æ± æ§è¡
2. submit(); æäº¤ä»»å¡ï¼è½å¤è¿åæ§è¡ç»æexecute + Future
3. shutdown(); å
³éçº¿ç¨æ± ï¼çå¾
ä»»å¡é½æ§è¡å®
4. shutdownNow(); ç«å³å
³éçº¿ç¨æ± ï¼ä¸çå¾
任塿§è¡å®
#### çº¿ç¨æ±
> é
ç½®
1. CPUå¯éåï¼è®¾ç½®ä¸ºN + 1
2. IOå¯éåï¼è®¾ç½®ä¸º2N
> å建
* 使ç¨Executorså·¥å
·ç±»åå»ºçº¿ç¨æ±
* 使ç¨ThreadPoolExecutorç±»åå»ºçº¿ç¨æ±
* 使ç¨ScheduledThreadPoolExecutorç±»åå»ºçº¿ç¨æ±
### 建议
1. SimpleDateFormatç±»æ¯çº¿ç¨ä¸å®å
¨çï¼æ¨è使ç¨JDK8ä¸çDateTimeFormatterï¼é«å¹¶ååºæ¯ä¸æ¨è使ç¨joda-timeåºæ¥å¤çæ¥æ ¼å¼åï¼æçé«
`protected Calendar calendar;`å¤ä¸ªçº¿ç¨ä¹é´å
±äº«åécalendarï¼å¹¶ä¿®æ¹calendarãå æ¤å¨å¤çº¿ç¨ç¯å¢ä¸ï¼å½å¤ä¸ªçº¿ç¨åæ¶ä½¿ç¨ç¸åçSimpleDateFormat对象ï¼å¦static修饰ï¼çè¯ï¼å¦è°ç¨formatæ¹æ³æ¶ï¼å¤ä¸ªçº¿ç¨ä¼åæ¶è°ç¨calender.setTimeæ¹æ³ï¼å¯¼è´time被å«ç线ç¨ä¿®æ¹ï¼å æ¤çº¿ç¨æ¯ä¸å®å
¨çã
# å¼ç¨
* https://www.cnblogs.com/skywang12345/
* https://www.cnblogs.com/walixiansheng/p/9588603.html
* https://segmentfault.com/u/niteip/articles?sort=vote
* https://www.cnblogs.com/qq1290511257/p/10645106.html
* https://www.cnblogs.com/developer_chan/p/10391365.html
* https://www.exception.site/java-concurrency/java-concurrency-hook-thread