---
sidebar: heading
---
> 欢è¿å å
¥[大彬çå¦ä¹ å](https://topjavaer.cn/zsxq/introduce.html)ï¼å¦ä¹ åæ´çäºææ°ç**Javaé¢è¯æå宿´ç**ï¼æ¬ç½ç«çé¢è¯é¢è¡¥å
çï¼æ´å
¨é¢ï¼ï¼è¿æå¾å¤å
¶ä»**ä¼è´¨èµæ**ï¼æ¯å¦å
æ¬Java项ç®ãè¿é¶ç¥è¯ã宿ç»éªæ»ç»ãä¼è´¨ä¹¦ç±ãç¬è¯é¢è¯èµæºççã
>
> 
>
> 
>
> 
>
> **ä¸å±ä¸å¯¹ä¸çæé®çç**ï¼å¸®ä½ è§£çåç§çé¾é®é¢ï¼å
æ¬èªå¦Java路线ãèä¸è§åãé¢è¯é®é¢ççã大彬ä¼**ä¼å
è§£ç**çåçé®é¢ã
>
> 
>
> 
>
> [大彬çå¦ä¹ å](https://topjavaer.cn/zsxq/introduce.html)**å å
¥æ¹å¼**ï¼
>
> 
## çº¿ç¨æ±
çº¿ç¨æ± ï¼ä¸ä¸ªç®¡ç线ç¨çæ± åã
### 为ä»ä¹å¹³æ¶é½æ¯ä½¿ç¨çº¿ç¨æ± å建线ç¨ï¼ç´æ¥newä¸ä¸ªçº¿ç¨ä¸å¥½åï¼
å¯ï¼æå¨åå»ºçº¿ç¨æä¸¤ä¸ªç¼ºç¹
1. ä¸åæ§é£é©
2. é¢ç¹å建å¼é大
**为ä»ä¹ä¸åæ§**ï¼
ç³»ç»èµæºæéï¼æ¯ä¸ªäººé对ä¸åä¸å¡é½å¯ä»¥æå¨å建线ç¨ï¼å¹¶ä¸åå»ºçº¿ç¨æ²¡æç»ä¸æ åï¼æ¯å¦å建ççº¿ç¨ææ²¡æååçãå½ç³»ç»è¿è¡èµ·æ¥ï¼ææçº¿ç¨é½å¨æ¢å èµæºï¼æ¯«æ è§åï¼æ··ä¹±åºé¢å¯æ³èç¥ï¼ä¸å¥½ç®¡æ§ã
**é¢ç¹æå¨å建线ç¨ä¸ºä»ä¹å¼éä¼å¤§ï¼è·new Object() æä»ä¹å·®å«ï¼**
è½ç¶Javaä¸ä¸ç©ç对象ï¼ä½æ¯new Thread() å建ä¸ä¸ªçº¿ç¨å new Object()è¿æ¯æåºå«çã
new Object()è¿ç¨å¦ä¸ï¼
1. JVMåé
ä¸åå
å M
2. å¨å
å M ä¸åå§å该对象
3. å°å
å M çå°åèµå¼ç»å¼ç¨åé obj
å建线ç¨çè¿ç¨å¦ä¸ï¼
1. JVM为ä¸ä¸ªçº¿ç¨æ åé
å
åï¼è¯¥æ 为æ¯ä¸ªçº¿ç¨æ¹æ³è°ç¨ä¿åä¸ä¸ªæ 帧
2. æ¯ä¸æ 帧ç±ä¸ä¸ªå±é¨åéæ°ç»ãè¿åå¼ãæä½æ°å æ å叏鿱 ç»æ
3. æ¯ä¸ªçº¿ç¨è·å¾ä¸ä¸ªç¨åºè®¡æ°å¨ï¼ç¨äºè®°å½å½åèææºæ£å¨æ§è¡ççº¿ç¨æä»¤å°å
4. ç³»ç»å建ä¸ä¸ªä¸Java线ç¨å¯¹åºçæ¬æºçº¿ç¨
5. å°ä¸çº¿ç¨ç¸å
³çæè¿°ç¬¦æ·»å å°JVMå
鍿°æ®ç»æä¸
6. 线ç¨å
±äº«å åæ¹æ³åºå
å建ä¸ä¸ªçº¿ç¨å¤§æ¦éè¦1Må·¦å³ç空é´ï¼Java8ï¼æºå¨è§æ ¼2c8Gï¼ãå¯è§ï¼é¢ç¹æå¨å建/éæ¯çº¿ç¨ç代价æ¯é常大çã
### 为ä»ä¹ä½¿ç¨çº¿ç¨æ± ï¼
- **éä½èµæºæ¶è**ãéè¿éå¤å©ç¨å·²å建ç线ç¨éä½çº¿ç¨å建åéæ¯é æçæ¶èã
- **æé«ååºé度**ãå½ä»»å¡å°è¾¾æ¶ï¼å¯ä»¥ä¸éè¦çå°çº¿ç¨å建就è½ç«å³æ§è¡ã
- **æé«çº¿ç¨çå¯ç®¡çæ§**ãç»ä¸ç®¡ç线ç¨ï¼é¿å
ç³»ç»å建大éå类线ç¨èå¯¼è´æ¶èå®å
åã
### çº¿ç¨æ± æ§è¡åçï¼

1. å½çº¿ç¨æ± éåæ´»ççº¿ç¨æ°å°äºæ ¸å¿çº¿ç¨æ°`corePoolSize`æ¶ï¼è¿æ¶å¯¹äºä¸ä¸ªæ°æäº¤çä»»å¡ï¼çº¿ç¨æ± ä¼å建ä¸ä¸ªçº¿ç¨å»å¤çä»»å¡ãå½çº¿ç¨æ± éé¢åæ´»ççº¿ç¨æ°å°äºçäºæ ¸å¿çº¿ç¨æ°`corePoolSize`æ¶ï¼çº¿ç¨æ± éé¢ç线ç¨ä¼ä¸ç´åæ´»çï¼å°±ç®ç©ºé²æ¶é´è¶
è¿äº`keepAliveTime`ï¼çº¿ç¨ä¹ä¸ä¼è¢«éæ¯ï¼èæ¯ä¸ç´é»å¡å¨é£éä¸ç´çå¾
ä»»å¡éåç任塿¥æ§è¡ã
2. å½çº¿ç¨æ± éé¢åæ´»ççº¿ç¨æ°å·²ç»çäºcorePoolSizeäºï¼è¿æ¯å¯¹äºä¸ä¸ªæ°æäº¤çä»»å¡ï¼ä¼è¢«æ¾è¿ä»»å¡éåworkQueueæéçå¾
æ§è¡ã
3. å½çº¿ç¨æ± éé¢åæ´»ççº¿ç¨æ°å·²ç»çäº`corePoolSize`äºï¼å¹¶ä¸ä»»å¡éå乿»¡äºï¼å设`maximumPoolSize>corePoolSize`ï¼è¿æ¶å¦æåæ¥æ°çä»»å¡ï¼çº¿ç¨æ± å°±ä¼ç»§ç»å建æ°ççº¿ç¨æ¥å¤çæ°çä»»å¡ï¼ç¥éçº¿ç¨æ°è¾¾å°`maximumPoolSize`ï¼å°±ä¸ä¼åå建äºã
4. 妿å½åççº¿ç¨æ°è¾¾å°äº`maximumPoolSize`ï¼å¹¶ä¸ä»»å¡éå乿»¡äºï¼å¦æè¿ææ°çä»»å¡è¿æ¥ï¼é£å°±ç´æ¥éç¨æç»çç¥è¿è¡å¤çãé»è®¤çæç»çç¥æ¯æåºä¸ä¸ªRejectedExecutionExceptionå¼å¸¸ã
### çº¿ç¨æ± åæ°æåªäºï¼
ThreadPoolExecutor çéç¨æé 彿°ï¼
```
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler);
```
1ã`corePoolSize`ï¼å½ææ°ä»»å¡æ¶ï¼å¦æçº¿ç¨æ± ä¸çº¿ç¨æ°æ²¡æè¾¾å°çº¿ç¨æ± çåºæ¬å¤§å°ï¼åä¼å建æ°ççº¿ç¨æ§è¡ä»»å¡ï¼å¦åå°ä»»å¡æ¾å
¥é»å¡éåãå½çº¿ç¨æ± ä¸åæ´»ççº¿ç¨æ°æ»æ¯å¤§äº corePoolSize æ¶ï¼åºè¯¥èèè°å¤§ corePoolSizeã
2ã`maximumPoolSize`ï¼å½é»å¡éå填满æ¶ï¼å¦æçº¿ç¨æ± ä¸çº¿ç¨æ°æ²¡æè¶
è¿æå¤§çº¿ç¨æ°ï¼åä¼å建æ°ç线ç¨è¿è¡ä»»å¡ãå¦åæ ¹æ®æç»çç¥å¤çæ°ä»»å¡ãéæ ¸å¿çº¿ç¨ç±»ä¼¼äºä¸´æ¶åæ¥çèµæºï¼è¿äºçº¿ç¨å¨ç©ºé²æ¶é´è¶
è¿ keepAliveTime ä¹åï¼å°±åºè¯¥éåºï¼é¿å
èµæºæµªè´¹ã
3ã`BlockingQueue`ï¼åå¨çå¾
è¿è¡çä»»å¡ã
4ã`keepAliveTime`ï¼**éæ ¸å¿çº¿ç¨**空é²åï¼ä¿æåæ´»çæ¶é´ï¼æ¤åæ°åªå¯¹éæ ¸å¿çº¿ç¨ææã设置为0ï¼è¡¨ç¤ºå¤ä½ç空é²çº¿ç¨ä¼è¢«ç«å³ç»æ¢ã
5ã`TimeUnit`ï¼æ¶é´åä½
```java
TimeUnit.DAYS
TimeUnit.HOURS
TimeUnit.MINUTES
TimeUnit.SECONDS
TimeUnit.MILLISECONDS
TimeUnit.MICROSECONDS
TimeUnit.NANOSECONDS
```
6ã`ThreadFactory`ï¼æ¯å½çº¿ç¨æ± å建ä¸ä¸ªæ°ççº¿ç¨æ¶ï¼é½æ¯éè¿çº¿ç¨å·¥åæ¹æ³æ¥å®æçãå¨ ThreadFactory ä¸åªå®ä¹äºä¸ä¸ªæ¹æ³ newThreadï¼æ¯å½çº¿ç¨æ± éè¦å建æ°çº¿ç¨å°±ä¼è°ç¨å®ã
```java
public class MyThreadFactory implements ThreadFactory {
private final String poolName;
public MyThreadFactory(String poolName) {
this.poolName = poolName;
}
public Thread newThread(Runnable runnable) {
return new MyAppThread(runnable, poolName);//å°çº¿ç¨æ± ååä¼ éç»æé 彿°ï¼ç¨äºåºåä¸åçº¿ç¨æ± ç线ç¨
}
}
```
7ã`RejectedExecutionHandler`ï¼å½éååçº¿ç¨æ± 齿»¡äºçæ¶åï¼æ ¹æ®æç»çç¥å¤çæ°ä»»å¡ã
```java
AbortPolicyï¼é»è®¤ççç¥ï¼ç´æ¥æåºRejectedExecutionException
DiscardPolicyï¼ä¸å¤çï¼ç´æ¥ä¸¢å¼
DiscardOldestPolicyï¼å°çå¾
éåéé¦çä»»å¡ä¸¢å¼ï¼å¹¶æ§è¡å½åä»»å¡
CallerRunsPolicyï¼ç±è°ç¨çº¿ç¨å¤ç该任å¡
```
### çº¿ç¨æ± 大尿ä¹è®¾ç½®ï¼
å¦æçº¿ç¨æ± çº¿ç¨æ°é太å°ï¼å½æå¤§é请æ±éè¦å¤çï¼ç³»ç»ååºæ¯è¾æ
¢ï¼ä¼å½±åç¨æ·ä½éªï¼çè³ä¼åºç°ä»»å¡éå大éå 积任å¡å¯¼è´OOMã
å¦æçº¿ç¨æ± çº¿ç¨æ°éè¿å¤§ï¼å¤§é线ç¨å¯è½ä¼åæ¶æ¢å CPU èµæºï¼è¿æ ·ä¼å¯¼è´å¤§éçä¸ä¸æåæ¢ï¼ä»èå¢å 线ç¨çæ§è¡æ¶é´ï¼å½±åäºæ§è¡æçã
**CPU å¯éåä»»å¡(N+1)**ï¼ è¿ç§ä»»å¡æ¶èçä¸»è¦æ¯ CPU èµæºï¼å¯ä»¥å°çº¿ç¨æ°è®¾ç½®ä¸º` Nï¼CPU æ ¸å¿æ°ï¼+1`ï¼å¤åºæ¥çä¸ä¸ªçº¿ç¨æ¯ä¸ºäºé²æ¢æäºåå 导è´ç线ç¨é»å¡ï¼å¦IOæä½ï¼çº¿ç¨sleepï¼çå¾
éï¼è带æ¥çå½±åã䏿¦æä¸ªçº¿ç¨è¢«é»å¡ï¼éæ¾äºCPUèµæºï¼èå¨è¿ç§æ
åµä¸å¤åºæ¥çä¸ä¸ªçº¿ç¨å°±å¯ä»¥å
åå©ç¨ CPU çç©ºé²æ¶é´ã
**I/O å¯éåä»»å¡(2N)**ï¼ ç³»ç»ç大é¨åæ¶é´é½å¨å¤ç IO æä½ï¼æ¤æ¶çº¿ç¨å¯è½ä¼è¢«é»å¡ï¼éæ¾CPUèµæºï¼è¿æ¶å°±å¯ä»¥å° CPU 交åºç»å
¶å®çº¿ç¨ä½¿ç¨ãå æ¤å¨ IO å¯éåä»»å¡çåºç¨ä¸ï¼å¯ä»¥å¤é
ç½®ä¸äºçº¿ç¨ï¼å
·ä½çè®¡ç®æ¹æ³ï¼`æä½³çº¿ç¨æ° = CPUæ ¸å¿æ° * (1/CPUå©ç¨ç) = CPUæ ¸å¿æ° * (1 + (IOèæ¶/CPUèæ¶))`ï¼ä¸è¬å¯è®¾ç½®ä¸º2Nã
### çº¿ç¨æ± çç±»åæåªäºï¼éç¨åºæ¯ï¼
常è§ççº¿ç¨æ± æ `FixedThreadPool`ã`SingleThreadExecutor`ã`CachedThreadPool` å `ScheduledThreadPool`ãè¿å ä¸ªé½æ¯ `ExecutorService` çº¿ç¨æ± å®ä¾ã
**FixedThreadPool**
åºå®çº¿ç¨æ°ççº¿ç¨æ± ã任使¶é´ç¹ï¼æå¤åªæ nThreads 个线ç¨å¤äºæ´»å¨ç¶ææ§è¡ä»»å¡ã
```
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
}
```
ä½¿ç¨æ çéå LinkedBlockingQueueï¼éå容é为 Integer.MAX_VALUEï¼ï¼è¿è¡ä¸ççº¿ç¨æ± ä¸ä¼æç»ä»»å¡ï¼å³ä¸ä¼è°ç¨RejectedExecutionHandler.rejectedExecution()æ¹æ³ã
maxThreadPoolSize æ¯æ æåæ°ï¼æ
å°å®çå¼è®¾ç½®ä¸ºä¸ coreThreadPoolSize ä¸è´ã
keepAliveTime 乿¯æ æåæ°ï¼è®¾ç½®ä¸º0Lï¼å 为æ¤çº¿ç¨æ± éææçº¿ç¨é½æ¯æ ¸å¿çº¿ç¨ï¼æ ¸å¿çº¿ç¨ä¸ä¼è¢«åæ¶ï¼é¤é设置äºexecutor.allowCoreThreadTimeOut(true)ï¼ã
éç¨åºæ¯ï¼éç¨äºå¤çCPUå¯éåçä»»å¡ï¼ç¡®ä¿CPUå¨é¿æè¢«å·¥ä½çº¿ç¨ä½¿ç¨çæ
åµä¸ï¼å°½å¯è½çå°çåé
线ç¨ï¼å³éç¨æ§è¡é¿æçä»»å¡ãéè¦æ³¨æçæ¯ï¼FixedThreadPool ä¸ä¼æç»ä»»å¡ï¼**å¨ä»»å¡æ¯è¾å¤çæ¶åä¼å¯¼è´ OOMã**
**SingleThreadExecutor**
åªæä¸ä¸ªçº¿ç¨ççº¿ç¨æ± ã
```
public static ExecutionService newSingleThreadExecutor() {
return new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
}
```
ä½¿ç¨æ çéå LinkedBlockingQueueãçº¿ç¨æ± åªæä¸ä¸ªè¿è¡ç线ç¨ï¼æ°æ¥ç任塿¾å
¥å·¥ä½éåï¼çº¿ç¨å¤çå®ä»»å¡å°±å¾ªç¯ä»éåéè·å任塿§è¡ãä¿è¯é¡ºåºçæ§è¡å个任å¡ã
éç¨åºæ¯ï¼éç¨äºä¸²è¡æ§è¡ä»»å¡çåºæ¯ï¼ä¸ä¸ªä»»å¡ä¸ä¸ªä»»å¡å°æ§è¡ã**å¨ä»»å¡æ¯è¾å¤çæ¶å乿¯ä¼å¯¼è´ OOMã**
**CachedThreadPool**
æ ¹æ®éè¦å建æ°çº¿ç¨ççº¿ç¨æ± ã
```
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue());
}
```
å¦æä¸»çº¿ç¨æäº¤ä»»å¡çé度é«äºçº¿ç¨å¤çä»»å¡çé度æ¶ï¼`CachedThreadPool` ä¼ä¸æå建æ°ç线ç¨ãæç«¯æ
åµä¸ï¼è¿æ ·ä¼å¯¼è´èå°½ cpu åå
åèµæºã
ä½¿ç¨æ²¡æå®¹éçSynchronousQueueä½ä¸ºçº¿ç¨æ± å·¥ä½éåï¼å½çº¿ç¨æ± æç©ºé²çº¿ç¨æ¶ï¼`SynchronousQueue.offer(Runnable task)`æäº¤çä»»å¡ä¼è¢«ç©ºé²çº¿ç¨å¤çï¼å¦åä¼å建æ°ç线ç¨å¤çä»»å¡ã
éç¨åºæ¯ï¼ç¨äºå¹¶åæ§è¡å¤§éçæçå°ä»»å¡ã`CachedThreadPool`å
许å建ççº¿ç¨æ°é为 Integer.MAX_VALUE ï¼**å¯è½ä¼å建大é线ç¨ï¼ä»èå¯¼è´ OOMã**
**ScheduledThreadPoolExecutor**
å¨ç»å®çå»¶è¿åè¿è¡ä»»å¡ï¼æè
宿æ§è¡ä»»å¡ãå¨å®é
项ç®ä¸åºæ¬ä¸ä¼è¢«ç¨å°ï¼å 为æå
¶ä»æ¹æ¡éæ©æ¯å¦`quartz`ã
使ç¨çä»»å¡éå `DelayQueue` å°è£
äºä¸ä¸ª `PriorityQueue`ï¼`PriorityQueue` ä¼å¯¹éåä¸çä»»å¡è¿è¡æåºï¼æ¶é´æ©çä»»å¡å
被æ§è¡(å³`ScheduledFutureTask` ç `time` åéå°çå
æ§è¡)ï¼å¦ætimeç¸ååå
æäº¤çä»»å¡ä¼è¢«å
æ§è¡(`ScheduledFutureTask` ç `squenceNumber` åéå°çå
æ§è¡)ã
æ§è¡å¨æä»»å¡æ¥éª¤ï¼
1. 线ç¨ä» `DelayQueue` ä¸è·å已尿ç `ScheduledFutureTaskï¼DelayQueue.take()ï¼`ã尿任塿¯æ `ScheduledFutureTask`ç time 大äºçäºå½åç³»ç»çæ¶é´ï¼
2. æ§è¡è¿ä¸ª `ScheduledFutureTask`ï¼
3. ä¿®æ¹ `ScheduledFutureTask` ç time åéä¸ºä¸æ¬¡å°è¦è¢«æ§è¡çæ¶é´ï¼
4. æè¿ä¸ªä¿®æ¹ time ä¹åç `ScheduledFutureTask` æ¾å `DelayQueue` ä¸ï¼`DelayQueue.add()`)ã

éç¨åºæ¯ï¼å¨ææ§æ§è¡ä»»å¡çåºæ¯ï¼éè¦éå¶çº¿ç¨æ°éçåºæ¯ã
## è¿ç¨çº¿ç¨
è¿ç¨æ¯æä¸ä¸ªå
åä¸è¿è¡çåºç¨ç¨åºï¼æ¯ä¸ªè¿ç¨é½æèªå·±ç¬ç«çä¸åå
å空é´ã
çº¿ç¨æ¯æ¯è¿ç¨æ´å°çæ§è¡åä½ï¼å®æ¯å¨ä¸ä¸ªè¿ç¨ä¸ç¬ç«çæ§å¶æµï¼ä¸ä¸ªè¿ç¨å¯ä»¥å¯å¨å¤ä¸ªçº¿ç¨ï¼æ¯æ¡çº¿ç¨å¹¶è¡æ§è¡ä¸åçä»»å¡ã
### 线ç¨ççå½å¨æ
**åå§(NEW)**ï¼çº¿ç¨è¢«æå»ºï¼è¿æ²¡æè°ç¨ start()ã
**è¿è¡(RUNNABLE)**ï¼å
æ¬æä½ç³»ç»ç就绪åè¿è¡ä¸¤ç§ç¶æã
**é»å¡(BLOCKED)**ï¼ä¸è¬æ¯è¢«å¨çï¼å¨æ¢å èµæºä¸å¾ä¸å°èµæºï¼è¢«å¨çæèµ·å¨å
åï¼çå¾
èµæºéæ¾å°å
¶å¤éã线ç¨è¢«é»å¡ä¼éæ¾CPUï¼ä¸éæ¾å
åã
**çå¾
(WAITING)**ï¼è¿å
¥è¯¥ç¶æç线ç¨éè¦çå¾
å
¶ä»çº¿ç¨ååºä¸äºç¹å®å¨ä½ï¼éç¥æä¸æï¼ã
**è¶
æ¶çå¾
(TIMED_WAITING)**ï¼è¯¥ç¶æä¸åäºWAITINGï¼å®å¯ä»¥å¨æå®çæ¶é´åèªè¡è¿åã
**ç»æ¢(TERMINATED)**ï¼è¡¨ç¤ºè¯¥çº¿ç¨å·²ç»æ§è¡å®æ¯ã

> å¾çæ¥æºï¼Javaå¹¶åç¼ç¨çèºæ¯
### 讲讲线ç¨ä¸æï¼
线ç¨ä¸æå³çº¿ç¨è¿è¡è¿ç¨ä¸è¢«å
¶ä»çº¿ç¨ç»ææäºï¼å®ä¸ stop æå¤§çåºå«æ¯ï¼stop æ¯ç±ç³»ç»å¼ºå¶ç»æ¢çº¿ç¨ï¼è线ç¨ä¸æåæ¯ç»ç®æ 线ç¨åéä¸ä¸ªä¸æä¿¡å·ï¼å¦æç®æ çº¿ç¨æ²¡ææ¥æ¶çº¿ç¨ä¸æçä¿¡å·å¹¶ç»æçº¿ç¨ï¼çº¿ç¨åä¸ä¼ç»æ¢ï¼å
·ä½æ¯å¦éåºæè
æ§è¡å
¶ä»é»è¾åå³äºç®æ 线ç¨ã
线ç¨ä¸æä¸ä¸ªéè¦çæ¹æ³ï¼
**1ãjava.lang.Thread#interrupt**
è°ç¨ç®æ 线ç¨ç`interrupt()`æ¹æ³ï¼ç»ç®æ 线ç¨åä¸ä¸ªä¸æä¿¡å·ï¼çº¿ç¨è¢«æä¸ä¸ææ è®°ã
**2ãjava.lang.Thread#isInterrupted()**
å¤æç®æ çº¿ç¨æ¯å¦è¢«ä¸æï¼ä¸ä¼æ¸
é¤ä¸ææ è®°ã
**3ãjava.lang.Thread#interrupted**
å¤æç®æ çº¿ç¨æ¯å¦è¢«ä¸æï¼ä¼æ¸
é¤ä¸ææ è®°ã
```java
private static void test2() {
Thread thread = new Thread(() -> {
while (true) {
Thread.yield();
// ååºä¸æ
if (Thread.currentThread().isInterrupted()) {
System.out.println("Javaææ¯æ 线ç¨è¢«ä¸æï¼ç¨åºéåºã");
return;
}
}
});
thread.start();
thread.interrupt();
}
```
### åå»ºçº¿ç¨æåªå ç§æ¹å¼ï¼
- éè¿æ©å±`Thread`ç±»æ¥å建å¤çº¿ç¨
- éè¿å®ç°`Runnable`æ¥å£æ¥å建å¤çº¿ç¨
- å®ç°`Callable`æ¥å£ï¼éè¿`FutureTask`æ¥å£å建线ç¨ã
- 使ç¨`Executor`æ¡æ¶æ¥åå»ºçº¿ç¨æ± ã
**ç»§æ¿ Thread å建线ç¨**代ç å¦ä¸ãrun()æ¹æ³æ¯ç±jvmåå»ºå®æä½ç³»ç»çº§çº¿ç¨ååè°çæ¹æ³ï¼ä¸å¯ä»¥æå¨è°ç¨ï¼æå¨è°ç¨ç¸å½äºè°ç¨æ®éæ¹æ³ã
```java
/**
* @author: ç¨åºå大彬
* @time: 2021-09-11 10:15
*/
public class MyThread extends Thread {
public MyThread() {
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread() + ":" + i);
}
}
public static void main(String[] args) {
MyThread mThread1 = new MyThread();
MyThread mThread2 = new MyThread();
MyThread myThread3 = new MyThread();
mThread1.start();
mThread2.start();
myThread3.start();
}
}
```
**Runnable å建线ç¨ä»£ç **ï¼
```java
/**
* @author: ç¨åºå大彬
* @time: 2021-09-11 10:04
*/
public class RunnableTest {
public static void main(String[] args){
Runnable1 r = new Runnable1();
Thread thread = new Thread(r);
thread.start();
System.out.println("主线ç¨ï¼["+Thread.currentThread().getName()+"]");
}
}
class Runnable1 implements Runnable{
@Override
public void run() {
System.out.println("å½å线ç¨ï¼"+Thread.currentThread().getName());
}
}
```
å®ç°Runnableæ¥å£æ¯ç»§æ¿Threadç±»æå
·æçä¼å¿ï¼
1. å¯ä»¥é¿å
javaä¸çåç»§æ¿çéå¶
3. çº¿ç¨æ± åªè½æ¾å
¥å®ç°RunableæCallable类线ç¨ï¼ä¸è½ç´æ¥æ¾å
¥ç»§æ¿Threadçç±»
**Callable å建线ç¨ä»£ç **ï¼
```java
/**
* @author: ç¨åºå大彬
* @time: 2021-09-11 10:21
*/
public class CallableTest {
public static void main(String[] args) {
Callable1 c = new Callable1();
//弿¥è®¡ç®çç»æ
FutureTask result = new FutureTask<>(c);
new Thread(result).start();
try {
//çå¾
ä»»å¡å®æï¼è¿åç»æ
int sum = result.get();
System.out.println(sum);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
class Callable1 implements Callable {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
return sum;
}
}
```
**ä½¿ç¨ Executor å建线ç¨ä»£ç **ï¼
```java
/**
* @author: ç¨åºå大彬
* @time: 2021-09-11 10:44
*/
public class ExecutorsTest {
public static void main(String[] args) {
//è·åExecutorServiceå®ä¾ï¼ç产ç¦ç¨ï¼éè¦æå¨åå»ºçº¿ç¨æ±
ExecutorService executorService = Executors.newCachedThreadPool();
//æäº¤ä»»å¡
executorService.submit(new RunnableDemo());
}
}
class RunnableDemo implements Runnable {
@Override
public void run() {
System.out.println("大彬");
}
}
```
### ä»ä¹æ¯çº¿ç¨æ»éï¼
çº¿ç¨æ»éæ¯æä¸¤ä¸ªæä¸¤ä¸ªä»¥ä¸ç线ç¨å¨æ§è¡è¿ç¨ä¸ï¼å äºå¤ºèµæºèé æçä¸ç§äºç¸çå¾
çç°è±¡ãè¥æ å¤åä½ç¨ï¼å®ä»¬é½å°æ æ³æ¨è¿ä¸å»ã
å¦ä¸å¾æç¤ºï¼çº¿ç¨ A ææèµæº 2ï¼çº¿ç¨ B ææèµæº 1ï¼ä»ä»¬åæ¶é½æ³ç³è¯·å¯¹æ¹ææçèµæºï¼æä»¥è¿ä¸¤ä¸ªçº¿ç¨å°±ä¼äºç¸çå¾
èè¿å
¥æ»éç¶æã

ä¸é¢éè¿ä¾å说æçº¿ç¨æ»éï¼ä»£ç æ¥èªå¹¶åç¼ç¨ä¹ç¾ã
```java
public class DeadLockDemo {
private static Object resource1 = new Object();//èµæº 1
private static Object resource2 = new Object();//èµæº 2
public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}, "çº¿ç¨ 1").start();
new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
}
}
}, "çº¿ç¨ 2").start();
}
}
```
代ç è¾åºå¦ä¸ï¼
```java
Thread[çº¿ç¨ 1,5,main]get resource1
Thread[çº¿ç¨ 2,5,main]get resource2
Thread[çº¿ç¨ 1,5,main]waiting get resource2
Thread[çº¿ç¨ 2,5,main]waiting get resource1
```
çº¿ç¨ A éè¿ `synchronized` (resource1) è·å¾ resource1 ççè§å¨éï¼ç¶åéè¿ `Thread.sleep(1000)`ãè®©çº¿ç¨ A ä¼ç 1s ä¸ºçæ¯è®©çº¿ç¨ B å¾å°æ§è¡ç¶åè·åå° resource2 ççè§å¨éãçº¿ç¨ A åçº¿ç¨ B ä¼ç ç»æäºé½å¼å§ä¼å¾è¯·æ±è·å对æ¹çèµæºï¼ç¶åè¿ä¸¤ä¸ªçº¿ç¨å°±ä¼é·å
¥äºç¸çå¾
çç¶æï¼è¿ä¹å°±äº§çäºæ»éã
### çº¿ç¨æ»éæä¹äº§çï¼æä¹é¿å
ï¼
**æ»é产ççå个å¿
è¦æ¡ä»¶**ï¼
- äºæ¥ï¼ä¸ä¸ªèµæºæ¯æ¬¡åªè½è¢«ä¸ä¸ªè¿ç¨ä½¿ç¨
- 请æ±ä¸ä¿æï¼ä¸ä¸ªè¿ç¨å 请æ±èµæºèé»å¡æ¶ï¼ä¸éæ¾è·å¾çèµæº
- ä¸å¥å¤ºï¼è¿ç¨å·²è·å¾çèµæºï¼å¨æªä½¿ç¨ä¹åï¼ä¸è½å¼ºè¡å¥å¤º
- 循ç¯çå¾
ï¼è¿ç¨ä¹é´å¾ªç¯çå¾
çèµæº
**é¿å
æ»éçæ¹æ³**ï¼
- äºæ¥æ¡ä»¶ä¸è½ç ´åï¼å 为å éå°±æ¯ä¸ºäºä¿è¯äºæ¥
- 䏿¬¡æ§ç³è¯·ææçèµæºï¼é¿å
线ç¨å æèµæºèä¸å¨çå¾
å
¶ä»èµæº
- å æé¨åèµæºç线ç¨è¿ä¸æ¥ç³è¯·å
¶ä»èµæºæ¶ï¼å¦æç³è¯·ä¸å°ï¼ä¸»å¨éæ¾å®å æçèµæº
- æåºç³è¯·èµæº
### 线ç¨runåstartçåºå«ï¼
- å½ç¨åºè°ç¨`start()`æ¹æ³ï¼å°ä¼å建ä¸ä¸ªæ°çº¿ç¨å»æ§è¡`run()`æ¹æ³ä¸ç代ç ã`run()`å°±åä¸ä¸ªæ®éæ¹æ³ä¸æ ·ï¼ç´æ¥è°ç¨`run()`çè¯ï¼ä¸ä¼å建æ°çº¿ç¨ã
- ä¸ä¸ªçº¿ç¨ç `start()` æ¹æ³åªè½è°ç¨ä¸æ¬¡ï¼å¤æ¬¡è°ç¨ä¼æåº java.lang.IllegalThreadStateException å¼å¸¸ã`run()` æ¹æ³å没æéå¶ã
### 线ç¨é½æåªäºæ¹æ³ï¼
**start**
ç¨äºå¯å¨çº¿ç¨ã
**getPriority**
è·å线ç¨ä¼å
级ï¼é»è®¤æ¯5ï¼çº¿ç¨é»è®¤ä¼å
级为5ï¼å¦æä¸æå¨æå®ï¼é£ä¹çº¿ç¨ä¼å
级å
·æç»§æ¿æ§ï¼æ¯å¦çº¿ç¨Aå¯å¨çº¿ç¨Bï¼é£ä¹çº¿ç¨Bçä¼å
级å线ç¨Açä¼å
级ç¸å
**setPriority**
设置线ç¨ä¼å
级ãCPUä¼å°½éå°æ§è¡èµæºè®©ç»ä¼å
级æ¯è¾é«ç线ç¨ã
**interrupt**
åè¯çº¿ç¨ï¼ä½ åºè¯¥ä¸æäºï¼å
·ä½å°åºä¸æè¿æ¯ç»§ç»è¿è¡ï¼ç±è¢«éç¥ç线ç¨èªå·±å¤çã
å½å¯¹ä¸ä¸ªçº¿ç¨è°ç¨ interrupt() æ¶ï¼æä¸¤ç§æ
åµï¼
1. å¦æçº¿ç¨å¤äºè¢«é»å¡ç¶æï¼ä¾å¦å¤äºsleep, wait, join çç¶æï¼ï¼é£ä¹çº¿ç¨å°ç«å³éåºè¢«é»å¡ç¶æï¼å¹¶æåºä¸ä¸ªInterruptedExceptionå¼å¸¸ã
2. å¦æçº¿ç¨å¤äºæ£å¸¸æ´»å¨ç¶æï¼é£ä¹ä¼å°è¯¥çº¿ç¨ç䏿æ å¿è®¾ç½®ä¸º trueãä¸è¿ï¼è¢«è®¾ç½®ä¸ææ å¿ç线ç¨å¯ä»¥ç»§ç»æ£å¸¸è¿è¡ï¼ä¸åå½±åã
interrupt() å¹¶ä¸è½çæ£çä¸æçº¿ç¨ï¼éè¦è¢«è°ç¨ç线ç¨èªå·±è¿è¡é
åæè¡ã
**join**
çå¾
å
¶ä»çº¿ç¨ç»æ¢ãå¨å½å线ç¨ä¸è°ç¨å¦ä¸ä¸ªçº¿ç¨çjoin()æ¹æ³ï¼åå½å线ç¨è½¬å
¥é»å¡ç¶æï¼ç´å°å¦ä¸ä¸ªè¿ç¨è¿è¡ç»æï¼å½å线ç¨åç±é»å¡è½¬ä¸ºå°±ç»ªç¶æã
**yield**
æåå½åæ£å¨æ§è¡ç线ç¨å¯¹è±¡ï¼ææ§è¡æºä¼è®©ç»ç¸åæè
æ´é«ä¼å
级ç线ç¨ã
**sleep**
使线ç¨è½¬å°é»å¡ç¶æãmillisåæ°è®¾å®ç¡ç çæ¶é´ï¼ä»¥æ¯«ç§ä¸ºåä½ãå½ç¡ç ç»æåï¼çº¿ç¨èªå¨è½¬ä¸ºRunnableç¶æã
## volatileåºå±åç
`volatile`æ¯è½»é级ç忥æºå¶ï¼`volatile`ä¿è¯åé对ææçº¿ç¨çå¯è§æ§ï¼ä¸ä¿è¯ååæ§ã
1. å½å¯¹`volatile`åéè¿è¡åæä½çæ¶åï¼JVMä¼åå¤çå¨åé䏿¡`LOCK`åç¼çæä»¤ï¼å°è¯¥åéæå¨ç¼åè¡çæ°æ®ååç³»ç»å
åã
2. ç±äºç¼åä¸è´æ§åè®®ï¼æ¯ä¸ªå¤çå¨éè¿å
æ¢å¨æ»çº¿ä¸ä¼ æçæ°æ®æ¥æ£æ¥èªå·±çç¼åæ¯ä¸æ¯è¿æäºï¼å½å¤çå¨åç°èªå·±ç¼åè¡å¯¹åºçå
åå°å被修æ¹ï¼å°±ä¼å°å½åå¤çå¨çç¼åè¡ç½®ä¸ºæ æç¶æï¼å½å¤çå¨å¯¹è¿ä¸ªæ°æ®è¿è¡ä¿®æ¹æä½çæ¶åï¼ä¼éæ°ä»ç³»ç»å
åä¸ææ°æ®è¯»å°å¤çå¨ç¼åä¸ã
> æ¥ççç¼åä¸è´æ§åè®®æ¯ä»ä¹ã
>
> **ç¼åä¸è´æ§åè®®**ï¼å½CPUåæ°æ®æ¶ï¼å¦æåç°æä½çå鿝å
±äº«åéï¼å³å¨å
¶ä»CPUä¸ä¹åå¨è¯¥åéç坿¬ï¼ä¼ååºä¿¡å·éç¥å
¶ä»CPUå°è¯¥åéçç¼åè¡ç½®ä¸ºæ æç¶æï¼å æ¤å½å
¶ä»CPUéè¦è¯»åè¿ä¸ªåéæ¶ï¼å°±ä¼ä»å
åéæ°è¯»åã
`volatile`å
³é®åç两个ä½ç¨ï¼
1. ä¿è¯äºä¸å线ç¨å¯¹å
±äº«åéè¿è¡æä½æ¶ç**å¯è§æ§**ï¼å³ä¸ä¸ªçº¿ç¨ä¿®æ¹äºæä¸ªåéçå¼ï¼è¿æ°å¼å¯¹å
¶ä»çº¿ç¨æ¥è¯´æ¯ç«å³å¯è§çã
2. ç¦æ¢è¿è¡**æä»¤éæåº**ã
> æä»¤éæåºæ¯JVM为äºä¼åæä»¤ï¼æé«ç¨åºè¿è¡æçï¼å¨ä¸å½±åå线ç¨ç¨åºæ§è¡ç»æçåæä¸ï¼å°½å¯è½å°æé«å¹¶è¡åº¦ãJavaç¼è¯å¨ä¼å¨çææä»¤ç³»åæ¶å¨éå½çä½ç½®ä¼æå
¥`å
åå±é`æä»¤æ¥ç¦æ¢å¤çå¨éæåºãæå
¥ä¸ä¸ªå
åå±éï¼ç¸å½äºåè¯CPUåç¼è¯å¨å
äºè¿ä¸ªå½ä»¤çå¿
é¡»å
æ§è¡ï¼åäºè¿ä¸ªå½ä»¤çå¿
须忧è¡ã对ä¸ä¸ªvolatileåæ®µè¿è¡åæä½ï¼Javaå
忍¡åå°å¨åæä½åæå
¥ä¸ä¸ªåå±éæä»¤ï¼è¿ä¸ªæä»¤ä¼æä¹åçåå
¥å¼é½å·æ°å°å
åã
## synchronizedçç¨æ³æåªäº?
1. **修饰æ®éæ¹æ³**ï¼ä½ç¨äºå½å对象å®ä¾ï¼è¿å
¥åæ¥ä»£ç åè¦è·å¾å½å对象å®ä¾çé
2. **ä¿®é¥°éææ¹æ³**ï¼ä½ç¨äºå½åç±»ï¼è¿å
¥åæ¥ä»£ç åè¦è·å¾å½å类对象çéï¼synchronizedå
³é®åå å°static éææ¹æ³å synchronized(class)代ç åä¸é½æ¯æ¯ç» Class ç±»ä¸é
3. **修饰代ç å**ï¼æå®å é对象ï¼å¯¹ç»å®å¯¹è±¡å éï¼è¿å
¥åæ¥ä»£ç åºåè¦è·å¾ç»å®å¯¹è±¡çé
## synchronizedçä½ç¨æåªäºï¼
**ååæ§**ï¼ç¡®ä¿çº¿ç¨äºæ¥ç访é®åæ¥ä»£ç ï¼
**å¯è§æ§**ï¼ä¿è¯å
±äº«åéçä¿®æ¹è½å¤åæ¶å¯è§ï¼
**æåºæ§**ï¼ææè§£å³éæåºé®é¢ã
## synchronized åºå±å®ç°åçï¼
synchronized 忥代ç åçå®ç°æ¯éè¿ `monitorenter` å `monitorexit` æä»¤ï¼å
¶ä¸ `monitorenter` æä»¤æå忥代ç åçå¼å§ä½ç½®ï¼`monitorexit` æä»¤åææåæ¥ä»£ç åçç»æä½ç½®ã彿§è¡ `monitorenter` æä»¤æ¶ï¼çº¿ç¨è¯å¾è·åéä¹å°±æ¯è·å `monitor`çæææï¼monitor对象åå¨äºæ¯ä¸ªJava对象ç对象头ä¸ï¼ synchronized é便æ¯éè¿è¿ç§æ¹å¼è·åéçï¼ä¹æ¯ä¸ºä»ä¹Javaä¸ä»»æå¯¹è±¡å¯ä»¥ä½ä¸ºéçåå ï¼ã
å
¶å
é¨å
å«ä¸ä¸ªè®¡æ°å¨ï¼å½è®¡æ°å¨ä¸º0åå¯ä»¥æåè·åï¼è·ååå°é计æ°å¨è®¾ä¸º1ä¹å°±æ¯å 1ãç¸åºç卿§è¡ `monitorexit` æä»¤åï¼å°é计æ°å¨è®¾ä¸º0
ï¼è¡¨æéè¢«éæ¾ã妿è·å对象é失败ï¼é£å½å线ç¨å°±è¦é»å¡çå¾
ï¼ç´å°é被å¦å¤ä¸ä¸ªçº¿ç¨éæ¾ä¸ºæ¢
synchronized ä¿®é¥°çæ¹æ³å¹¶æ²¡æ `monitorenter` æä»¤å `monitorexit` æä»¤ï¼åå¾ä»£ä¹çç¡®å®æ¯`ACC_SYNCHRONIZED` æ è¯ï¼è¯¥æ è¯ææäºè¯¥æ¹æ³æ¯ä¸ä¸ªåæ¥æ¹æ³ï¼JVM éè¿è¯¥ `ACC_SYNCHRONIZED` è®¿é®æ å¿æ¥è¾¨å«ä¸ä¸ªæ¹æ³æ¯å¦å£°æä¸ºåæ¥æ¹æ³ï¼ä»èæ§è¡ç¸åºç忥è°ç¨ã
## volatileåsynchronizedçåºå«æ¯ä»ä¹ï¼
1. `volatile`åªè½ä½¿ç¨å¨åéä¸ï¼è`synchronized`å¯ä»¥å¨ç±»ï¼åéï¼æ¹æ³å代ç åä¸ã
2. `volatile`è³ä¿è¯å¯è§æ§ï¼`synchronized`ä¿è¯ååæ§ä¸å¯è§æ§ã
3. `volatile`ç¦ç¨æä»¤éæåºï¼`synchronized`ä¸ä¼ã
4. `volatile`ä¸ä¼é æé»å¡ï¼`synchronized`ä¼ã
## ReentrantLockåsynchronizedåºå«
1. 使ç¨synchronizedå
³é®åå®ç°åæ¥ï¼çº¿ç¨æ§è¡å®åæ¥ä»£ç åä¼**èªå¨éæ¾é**ï¼èReentrantLockéè¦æå¨éæ¾éã
2. synchronizedæ¯**éå
¬å¹³é**ï¼ReentrantLockå¯ä»¥è®¾ç½®ä¸ºå
¬å¹³éã
3. ReentrantLockä¸çå¾
è·åéççº¿ç¨æ¯**å¯ä¸æç**ï¼çº¿ç¨å¯ä»¥æ¾å¼çå¾
éãèsynchonized伿 éæçå¾
ä¸å»ã
4. ReentrantLock **å¯ä»¥è®¾ç½®è¶
æ¶è·åé**ã卿å®çæªæ¢æ¶é´ä¹åè·åéï¼å¦ææªæ¢æ¶é´å°äºè¿æ²¡æè·åå°éï¼åè¿åã
5. ReentrantLock ç tryLock() æ¹æ³**å¯ä»¥å°è¯éé»å¡çè·åé**ï¼è°ç¨è¯¥æ¹æ³åç«å»è¿åï¼å¦æè½å¤è·ååè¿åtrueï¼å¦åè¿åfalseã
## wait()åsleep()çå¼åç¹ï¼
**ç¸åç¹**ï¼
1. å®ä»¬é½å¯ä»¥ä½¿å½åçº¿ç¨æåè¿è¡ï¼ææºä¼äº¤ç»å
¶ä»çº¿ç¨
2. ä»»ä½çº¿ç¨å¨è°ç¨wait()åsleep()ä¹åï¼å¨çå¾
æé´è¢«ä¸æé½ä¼æåº`InterruptedException`
**ä¸åç¹**ï¼
1. `wait()`æ¯Objectè¶
ç±»ä¸çæ¹æ³ï¼è`sleep()`æ¯çº¿ç¨Threadç±»ä¸çæ¹æ³
2. 对éçææä¸åï¼`wait()`ä¼éæ¾éï¼è`sleep()`å¹¶ä¸éæ¾é
3. å¤éæ¹æ³ä¸å®å
¨ç¸åï¼`wait()`ä¾é `notify`æè
`notifyAll `ã䏿ãè¾¾å°æå®æ¶é´æ¥å¤éï¼è`sleep()`å°è¾¾æå®æ¶é´è¢«å¤é
4. è°ç¨`wait()`éè¦å
è·å对象çéï¼è`Thread.sleep()`ä¸ç¨
## RunnableåCallableæä»ä¹åºå«ï¼
- Callableæ¥å£æ¹æ³æ¯`call()`ï¼Runnableçæ¹æ³æ¯`run()`ï¼
- Callableæ¥å£callæ¹æ³æè¿åå¼ï¼æ¯ææ³åï¼Runnableæ¥å£runæ¹æ³æ è¿åå¼ã
- Callableæ¥å£`call()`æ¹æ³å
许æåºå¼å¸¸ï¼èRunnableæ¥å£`run()`æ¹æ³ä¸è½ç»§ç»ä¸æå¼å¸¸ã
## çº¿ç¨æ§è¡é¡ºåºæä¹æ§å¶ï¼
å设æT1ãT2ãT3ä¸ä¸ªçº¿ç¨ï¼ä½ ææ ·ä¿è¯T2å¨T1æ§è¡å®åæ§è¡ï¼T3å¨T2æ§è¡å®åæ§è¡ï¼
å¯ä»¥ä½¿ç¨**joinæ¹æ³**è§£å³è¿ä¸ªé®é¢ãæ¯å¦å¨çº¿ç¨Aä¸ï¼è°ç¨çº¿ç¨Bçjoinæ¹æ³è¡¨ç¤ºçææå°±æ¯**ï¼Açå¾
Bçº¿ç¨æ§è¡å®æ¯åï¼éæ¾CPUæ§è¡æï¼ï¼å¨ç»§ç»æ§è¡ã**
代ç å¦ä¸ï¼
```
public class ThreadTest {
public static void main(String[] args) {
Thread spring = new Thread(new SeasonThreadTask("æ¥å¤©"));
Thread summer = new Thread(new SeasonThreadTask("å¤å¤©"));
Thread autumn = new Thread(new SeasonThreadTask("ç§å¤©"));
try
{
//æ¥å¤©çº¿ç¨å
å¯å¨
spring.start();
//主线ç¨çå¾
线ç¨springæ§è¡å®ï¼åå¾ä¸æ§è¡
spring.join();
//å¤å¤©çº¿ç¨åå¯å¨
summer.start();
//主线ç¨çå¾
线ç¨summeræ§è¡å®ï¼åå¾ä¸æ§è¡
summer.join();
//ç§å¤©çº¿ç¨æåå¯å¨
autumn.start();
//主线ç¨çå¾
线ç¨autumnæ§è¡å®ï¼åå¾ä¸æ§è¡
autumn.join();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
class SeasonThreadTask implements Runnable{
private String name;
public SeasonThreadTask(String name){
this.name = name;
}
@Override
public void run() {
for (int i = 1; i <4; i++) {
System.out.println(this.name + "æ¥äº: " + i + "次");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
```
è¿è¡ç»æï¼
```
æ¥å¤©æ¥äº: 1次
æ¥å¤©æ¥äº: 2次
æ¥å¤©æ¥äº: 3次
å¤å¤©æ¥äº: 1次
å¤å¤©æ¥äº: 2次
å¤å¤©æ¥äº: 3次
ç§å¤©æ¥äº: 1次
ç§å¤©æ¥äº: 2次
ç§å¤©æ¥äº: 3次
```
## 宿¤çº¿ç¨æ¯ä»ä¹ï¼
宿¤çº¿ç¨æ¯**è¿è¡å¨åå°çä¸ç§ç¹æ®è¿ç¨**ãå®ç¬ç«äºæ§å¶ç»ç«¯å¹¶ä¸å¨ææ§å°æ§è¡æç§ä»»å¡æçå¾
å¤çæäºåççäºä»¶ãå¨ Java ä¸åå¾åæ¶çº¿ç¨å°±æ¯ç¹æ®ç宿¤çº¿ç¨ã
## 线ç¨é´éä¿¡æ¹å¼
1ãä½¿ç¨ Object ç±»ç **wait()/notify()**ãObject ç±»æä¾äºçº¿ç¨é´éä¿¡çæ¹æ³ï¼`wait()`ã`notify()`ã`notifyAll()`ï¼å®ä»¬æ¯å¤çº¿ç¨éä¿¡çåºç¡ãå
¶ä¸ï¼`wait/notify` å¿
é¡»é
å `synchronized` 使ç¨ï¼wait æ¹æ³éæ¾éï¼notify æ¹æ³ä¸éæ¾éãwait æ¯æå¨ä¸ä¸ªå·²ç»è¿å
¥äºåæ¥éç线ç¨å
ï¼è®©èªå·±ææ¶è®©åºåæ¥éï¼ä»¥ä¾¿å
¶ä»æ£å¨çå¾
æ¤éç线ç¨å¯ä»¥å¾å°åæ¥éå¹¶è¿è¡ï¼åªæå
¶ä»çº¿ç¨è°ç¨äº`notify()`ï¼notifyå¹¶ä¸éæ¾éï¼åªæ¯åè¯è°ç¨è¿`wait()`ç线ç¨å¯ä»¥å»åä¸è·å¾éçç«äºäºï¼ä½ä¸æ¯é©¬ä¸å¾å°éï¼å 为éè¿å¨å«äººæéï¼å«äººè¿æ²¡éæ¾ï¼è°ç¨ `wait()` çä¸ä¸ªæå¤ä¸ªçº¿ç¨å°±ä¼è§£é¤ wait ç¶æï¼éæ°åä¸ç«äºå¯¹è±¡éï¼ç¨åºå¦æå¯ä»¥å次å¾å°éï¼å°±å¯ä»¥ç»§ç»åä¸è¿è¡ã
2ãä½¿ç¨ **volatile** å
³é®åãåºäºvolatileå
³é®åå®ç°çº¿ç¨é´ç¸äºéä¿¡ï¼å
¶åºå±ä½¿ç¨äºå
±äº«å
åãç®åæ¥è¯´ï¼å°±æ¯å¤ä¸ªçº¿ç¨åæ¶çå¬ä¸ä¸ªåéï¼å½è¿ä¸ªåéåçååçæ¶å ï¼çº¿ç¨è½å¤æç¥å¹¶æ§è¡ç¸åºçä¸å¡ã
3ã使ç¨JUCå·¥å
·ç±» **CountDownLatch**ãjdk1.5 ä¹åå¨`java.util.concurrent`å
䏿ä¾äºå¾å¤å¹¶åç¼ç¨ç¸å
³çå·¥å
·ç±»ï¼ç®åäºå¹¶åç¼ç¨å¼åï¼`CountDownLatch` åºäº AQS æ¡æ¶ï¼ç¸å½äºä¹æ¯ç»´æ¤äºä¸ä¸ªçº¿ç¨é´å
±äº«åé stateã
4ãåºäº **LockSupport** å®ç°çº¿ç¨é´çé»å¡åå¤éã`LockSupport` æ¯ä¸ç§éå¸¸çµæ´»çå®ç°çº¿ç¨é´é»å¡åå¤éçå·¥å
·ï¼ä½¿ç¨å®ä¸ç¨å
³æ³¨æ¯çå¾
线ç¨å
è¿è¡è¿æ¯å¤é线ç¨å
è¿è¡ï¼ä½æ¯å¾ç¥é线ç¨çååã
## ThreadLocal
çº¿ç¨æ¬å°åéãå½ä½¿ç¨`ThreadLocal`ç»´æ¤åéæ¶ï¼`ThreadLocal`为æ¯ä¸ªä½¿ç¨è¯¥åéççº¿ç¨æä¾ç¬ç«çåé坿¬ï¼æä»¥æ¯ä¸ä¸ªçº¿ç¨é½å¯ä»¥ç¬ç«å°æ¹åèªå·±ç坿¬ï¼èä¸ä¼å½±åå
¶å®çº¿ç¨ã
### ThreadLocalåç
æ¯ä¸ªçº¿ç¨é½æä¸ä¸ª`ThreadLocalMap`ï¼`ThreadLocal`å
é¨ç±»ï¼ï¼Mapä¸å
ç´ çé®ä¸º`ThreadLocal`ï¼èå¼å¯¹åºçº¿ç¨çåé坿¬ã

è°ç¨`threadLocal.set()`-->è°ç¨`getMap(Thread)`-->è¿åå½å线ç¨ç`ThreadLocalMap`-->`map.set(this, value)`ï¼thisæ¯`threadLocal`æ¬èº«ãæºç å¦ä¸ï¼
```java
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
```
è°ç¨`get()`-->è°ç¨`getMap(Thread)`-->è¿åå½å线ç¨ç`ThreadLocalMap`-->`map.getEntry(this)`ï¼è¿å`value`ãæºç å¦ä¸ï¼
```java
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
```
`threadLocals`çç±»å`ThreadLocalMap`çé®ä¸º`ThreadLocal`对象ï¼å 为æ¯ä¸ªçº¿ç¨ä¸å¯æå¤ä¸ª`threadLocal`åéï¼å¦`longLocal`å`stringLocal`ã
```
public class ThreadLocalDemo {
ThreadLocal longLocal = new ThreadLocal<>();
public void set() {
longLocal.set(Thread.currentThread().getId());
}
public Long get() {
return longLocal.get();
}
public static void main(String[] args) throws InterruptedException {
ThreadLocalDemo threadLocalDemo = new ThreadLocalDemo();
threadLocalDemo.set();
System.out.println(threadLocalDemo.get());
Thread thread = new Thread(() -> {
threadLocalDemo.set();
System.out.println(threadLocalDemo.get());
}
);
thread.start();
thread.join();
System.out.println(threadLocalDemo.get());
}
}
```
`ThreadLocal`并䏿¯ç¨æ¥è§£å³å
±äº«èµæºçå¤çº¿ç¨è®¿é®é®é¢ï¼å 为æ¯ä¸ªçº¿ç¨ä¸çèµæºåªæ¯å¯æ¬ï¼ä¸ä¼å
±äº«ãå æ¤`ThreadLocal`éåä½ä¸ºçº¿ç¨ä¸ä¸æåéï¼ç®å线ç¨å
ä¼ åã
### ThreadLocalå
åæ³æ¼çåå ï¼
æ¯ä¸ªçº¿ç¨é½æâ¼ä¸ª`ThreadLocalMap`çå
é¨å±æ§ï¼mapçkeyæ¯`ThreaLocal`ï¼å®ä¹ä¸ºå¼±å¼ç¨ï¼valueæ¯å¼ºå¼ç¨ç±»åãåå¾åæ¶çæ¶åä¼â¾å¨åæ¶keyï¼èvalueçåæ¶åå³äºThread对象ççå½å¨æãä¸è¬ä¼éè¿çº¿ç¨æ± çæ¹å¼å¤ç¨çº¿ç¨èçèµæºï¼è¿ä¹å°±å¯¼è´äºçº¿ç¨å¯¹è±¡ççå½å¨ææ¯è¾é¿ï¼è¿æ ·ä¾¿ä¸ç´åå¨ä¸æ¡å¼ºå¼ç¨é¾çå
³ç³»ï¼`Thread` --> `ThreadLocalMap`-->`Entry`-->`Value`ï¼éçä»»å¡çæ§è¡ï¼valueå°±æå¯è½è¶æ¥è¶å¤ä¸æ æ³éæ¾ï¼æç»å¯¼è´å
åæ³æ¼ã
è§£å³â½
æ³ï¼æ¯æ¬¡ä½¿â½¤å®`ThreadLocal`å°±è°â½¤å®ç`remove()`â½
æ³ï¼æå¨å°å¯¹åºçé®å¼å¯¹å é¤ï¼ä»â½½é¿å
å
åæ³æ¼ã
### ThreadLocal使ç¨åºæ¯æåªäºï¼
**åºæ¯1**
ThreadLocal ç¨ä½ä¿åæ¯ä¸ªçº¿ç¨ç¬äº«ç对象ï¼ä¸ºæ¯ä¸ªçº¿ç¨é½å建ä¸ä¸ªå¯æ¬ï¼è¿æ ·æ¯ä¸ªçº¿ç¨é½å¯ä»¥ä¿®æ¹èªå·±ææ¥æç坿¬, èä¸ä¼å½±åå
¶ä»çº¿ç¨ç坿¬ï¼ç¡®ä¿äºçº¿ç¨å®å
¨ã
è¿ç§åºæ¯é常ç¨äºä¿å线ç¨ä¸å®å
¨çå·¥å
·ç±»ï¼å
¸åç使ç¨çç±»å°±æ¯ SimpleDateFormatã
åå¦éæ±ä¸º500个线ç¨é½è¦ç¨å° SimpleDateFormatï¼ä½¿ç¨çº¿ç¨æ± æ¥å®ç°çº¿ç¨çå¤ç¨ï¼å¦å伿¶èè¿å¤çå
åçèµæºï¼å¦ææä»¬æ¯ä¸ªä»»å¡é½å建äºä¸ä¸ª simpleDateFormat 对象ï¼ä¹å°±æ¯è¯´ï¼500个任å¡å¯¹åº500个 simpleDateFormat 对象ã使¯è¿ä¹å¤å¯¹è±¡çåå»ºæ¯æå¼éçï¼èä¸è¿ä¹å¤å¯¹è±¡åæ¶åå¨å¨å
åä¸ä¹æ¯ä¸ç§å
åçæµªè´¹ãå¯ä»¥å°simpleDateFormat å¯¹è±¡ç»æåäºåºæ¥ï¼åæéæåéï¼ä½æ¯è¿æ ·ä¸æ¥å°±ä¼æçº¿ç¨ä¸å®å
¨çé®é¢ãæä»¬æ³è¦çæææ¯ï¼æ¢ä¸æµªè´¹è¿å¤çå
åï¼åæ¶åæ³ä¿è¯çº¿ç¨å®å
¨ãæ¤æ¶ï¼å¯ä»¥ä½¿ç¨ ThreadLocalæ¥è¾¾å°è¿ä¸ªç®çï¼æ¯ä¸ªçº¿ç¨é½æ¥æä¸ä¸ªèªå·±ç simpleDateFormat 对象ã
**åºæ¯2**
ThreadLocal ç¨ä½æ¯ä¸ªçº¿ç¨å
éè¦ç¬ç«ä¿åä¿¡æ¯ï¼ä»¥ä¾¿ä¾å
¶ä»æ¹æ³æ´æ¹ä¾¿å°è·å该信æ¯çåºæ¯ãæ¯ä¸ªçº¿ç¨è·åå°çä¿¡æ¯å¯è½é½æ¯ä¸ä¸æ ·çï¼å颿§è¡çæ¹æ³ä¿åäºä¿¡æ¯åï¼åç»æ¹æ³å¯ä»¥éè¿ ThreadLocal ç´æ¥è·åå°ï¼é¿å
äºä¼ åï¼ç±»ä¼¼äºå
¨å±åéçæ¦å¿µã
æ¯å¦Java webåºç¨ä¸ï¼æ¯ä¸ªçº¿ç¨æèªå·±åç¬ç`Session`å®ä¾ï¼å°±å¯ä»¥ä½¿ç¨`ThreadLocal`æ¥å®ç°ã
## AQSåç
AQSï¼`AbstractQueuedSynchronizer`ï¼æ½è±¡éå忥å¨ï¼å®ä¹äºä¸å¥å¤çº¿ç¨è®¿é®å
±äº«èµæºç忥卿¡æ¶ï¼è®¸å¤å¹¶åå·¥å
·çå®ç°é½ä¾èµäºå®ï¼å¦å¸¸ç¨ç`ReentrantLock/Semaphore/CountDownLatch`ã
AQS使ç¨ä¸ä¸ª`volatile`çintç±»åçæååé`state`æ¥è¡¨ç¤ºåæ¥ç¶æï¼éè¿CASä¿®æ¹åæ¥ç¶æçå¼ãå½çº¿ç¨è°ç¨ lock æ¹æ³æ¶ ï¼å¦æ `state`=0ï¼è¯´ææ²¡æä»»ä½çº¿ç¨å æå
±äº«èµæºçéï¼å¯ä»¥è·å¾éå¹¶å° `state`å 1ã妿 `state`ä¸ä¸º0ï¼å说ææçº¿ç¨ç®åæ£å¨ä½¿ç¨å
±äº«åéï¼å
¶ä»çº¿ç¨å¿
é¡»å å
¥åæ¥éåè¿è¡çå¾
ã
```java
private volatile int state;//å
±äº«åéï¼ä½¿ç¨volatile修饰ä¿è¯çº¿ç¨å¯è§æ§
```
忥å¨ä¾èµå
é¨ç忥éåï¼ä¸ä¸ªFIFOååéåï¼æ¥å®æåæ¥ç¶æç管çï¼å½å线ç¨è·ååæ¥ç¶æå¤±è´¥æ¶ï¼åæ¥å¨ä¼å°å½å线ç¨ä»¥åçå¾
ç¶æï¼ç¬å æå
±äº« ï¼æé æä¸ºä¸ä¸ªèç¹ï¼Nodeï¼å¹¶å°å
¶å å
¥åæ¥éåå¹¶è¿è¡èªæï¼å½åæ¥ç¶æéæ¾æ¶ï¼ä¼æé¦èç¹ä¸çåç»§èç¹å¯¹åºç线ç¨å¤éï¼ä½¿å
¶å次å°è¯è·ååæ¥ç¶æã

## ReentrantLock æ¯å¦ä½å®ç°å¯éå
¥æ§ç?
`ReentrantLock`å
é¨èªå®ä¹äºåæ¥å¨syncï¼å¨å éçæ¶åéè¿CASç®æ³ï¼å°çº¿ç¨å¯¹è±¡æ¾å°ä¸ä¸ªååé¾è¡¨ä¸ï¼æ¯æ¬¡è·åéçæ¶åï¼æ£æ¥å½åç»´æ¤çé£ä¸ªçº¿ç¨IDåå½å请æ±ç线ç¨IDæ¯å¦ ä¸è´ï¼å¦æä¸è´ï¼åæ¥ç¶æå 1ï¼è¡¨ç¤ºé被å½å线ç¨è·åäºå¤æ¬¡ã
æºç å¦ä¸ï¼
```java
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
```
## éçåç±»
### å
¬å¹³éä¸éå
¬å¹³é
æç
§**线ç¨è®¿é®é¡ºåº**è·å对象éã`synchronized`æ¯éå
¬å¹³éï¼`Lock`é»è®¤æ¯éå
¬å¹³éï¼å¯ä»¥è®¾ç½®ä¸ºå
¬å¹³éï¼å
¬å¹³éä¼å½±åæ§è½ã
```java
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
```
### å
±äº«å¼ä¸ç¬å å¼é
å
±äº«å¼ä¸ç¬å å¼çæä¸»è¦**åºå«**å¨äºï¼å䏿¶å»ç¬å å¼åªè½æ**ä¸ä¸ªçº¿ç¨**è·ååæ¥ç¶æï¼èå
±äº«å¼å¨å䏿¶å»å¯ä»¥æå¤ä¸ªçº¿ç¨è·ååæ¥ç¶æãä¾å¦è¯»æä½å¯ä»¥æå¤ä¸ªçº¿ç¨åæ¶è¿è¡ï¼èåæä½å䏿¶å»åªè½æä¸ä¸ªçº¿ç¨è¿è¡åæä½ï¼å
¶ä»æä½é½ä¼è¢«é»å¡ã
### æ²è§éä¸ä¹è§é
æ²è§éï¼**æ¯æ¬¡è®¿é®èµæºé½ä¼å é**ï¼æ§è¡å®åæ¥ä»£ç éæ¾éï¼`synchronized`å`ReentrantLock`å±äºæ²è§éã
ä¹è§éï¼ä¸ä¼éå®èµæºï¼ææç线ç¨é½è½è®¿é®å¹¶ä¿®æ¹åä¸ä¸ªèµæºï¼å¦ææ²¡æå²çªå°±ä¿®æ¹æåå¹¶éåºï¼å¦åå°±ä¼ç»§ç»å¾ªç¯å°è¯ãä¹è§éæå¸¸è§çå®ç°å°±æ¯`CAS`ã
éç¨åºæ¯ï¼
- æ²è§ééå**åæä½å¤**çåºæ¯ã
- ä¹è§ééå**读æä½å¤**çåºæ¯ï¼ä¸å éå¯ä»¥æå读æä½çæ§è½ã
## ä¹è§éæä»ä¹é®é¢?
ä¹è§éé¿å
äºæ²è§éç¬å 对象çé®é¢ï¼æé«äºå¹¶åæ§è½ï¼ä½å®ä¹æç¼ºç¹:
- ä¹è§éåªè½ä¿è¯**ä¸ä¸ªå
±äº«åé**çååæä½ã
- é¿æ¶é´èªæå¯è½å¯¼è´**å¼é大**ãåå¦CASé¿æ¶é´ä¸æåèä¸ç´èªæï¼ä¼ç»CPU带æ¥å¾å¤§çå¼éã
- **ABAé®é¢**ãCASçåçæ¯éè¿æ¯å¯¹å
åå¼ä¸é¢æå¼æ¯å¦ä¸æ ·è夿å
å弿¯å¦è¢«æ¹è¿ï¼ä½æ¯ä¼æä»¥ä¸é®é¢ï¼åå¦å
åå¼åæ¥æ¯Aï¼ åæ¥è¢«ä¸æ¡çº¿ç¨æ¹ä¸ºBï¼æååè¢«æ¹æäºAï¼åCAS认为æ¤å
åå¼å¹¶æ²¡æåçæ¹åãå¯ä»¥å¼å
¥çæ¬å·è§£å³è¿ä¸ªé®é¢ï¼æ¯æ¬¡åéæ´æ°é½æçæ¬å·å ä¸ã
## ä»ä¹æ¯CASï¼
CASå
¨ç§°`Compare And Swap`ï¼æ¯è¾ä¸äº¤æ¢ï¼æ¯ä¹è§éç主è¦å®ç°æ¹å¼ãCASå¨ä¸ä½¿ç¨éçæ
åµä¸å®ç°å¤çº¿ç¨ä¹é´çåé忥ã`ReentrantLock`å
é¨çAQSåååç±»å
é¨é½ä½¿ç¨äºCASã
CASç®æ³æ¶åå°ä¸ä¸ªæä½æ°ï¼
- éè¦è¯»åçå
åå¼Vã
- è¿è¡æ¯è¾çå¼Aã
- è¦åå
¥çæ°å¼Bã
åªæå½Vçå¼çäºAæ¶ï¼æä¼ä½¿ç¨ååæ¹å¼ç¨æ°å¼Bæ¥æ´æ°Vçå¼ï¼å¦åä¼ç»§ç»éè¯ç´å°æåæ´æ°å¼ã
以`AtomicInteger`为ä¾ï¼`AtomicInteger`ç`getAndIncrement()`æ¹æ³åºå±å°±æ¯CASå®ç°ï¼å
³é®ä»£ç æ¯ `compareAndSwapInt(obj, offset, expect, update)`ï¼å
¶å«ä¹å°±æ¯ï¼å¦æ`obj`å
ç`value`å`expect`ç¸çï¼å°±è¯ææ²¡æå
¶ä»çº¿ç¨æ¹åè¿è¿ä¸ªåéï¼é£ä¹å°±æ´æ°å®ä¸º`update`ï¼å¦æä¸ç¸çï¼é£å°±ä¼ç»§ç»éè¯ç´å°æåæ´æ°å¼ã
## CASåå¨çé®é¢ï¼
CAS ä¸å¤§é®é¢ï¼
1. **ABAé®é¢**ãCASéè¦å¨æä½å¼çæ¶åæ£æ¥å
å弿¯å¦åçååï¼æ²¡æåçååæä¼æ´æ°å
åå¼ã使¯å¦æå
åå¼åæ¥æ¯Aï¼åæ¥åæäºBï¼ç¶åååæäºAï¼é£ä¹CASè¿è¡æ£æ¥æ¶ä¼åç°å¼æ²¡æåçååï¼ä½æ¯å®é
䏿¯æååçãABAé®é¢çè§£å³æè·¯å°±æ¯å¨åéå颿·»å çæ¬å·ï¼æ¯æ¬¡åéæ´æ°çæ¶åé½æçæ¬å·å ä¸ï¼è¿æ ·ååè¿ç¨å°±ä»`Aï¼Bï¼A`åæäº`1Aï¼2Bï¼3A`ã
JDKä»1.5å¼å§æä¾äºAtomicStampedReferenceç±»æ¥è§£å³ABAé®é¢ï¼ååæ´æ°å¸¦æçæ¬å·çå¼ç¨ç±»åã
2. **å¾ªç¯æ¶é´é¿å¼é大**ãCASæä½å¦æé¿æ¶é´ä¸æåï¼ä¼å¯¼è´å
¶ä¸ç´èªæï¼ç»CPU带æ¥é常大çå¼éã
3. **åªè½ä¿è¯ä¸ä¸ªå
±äº«åéçååæä½**ã对ä¸ä¸ªå
±äº«åéæ§è¡æä½æ¶ï¼CASè½å¤ä¿è¯ååæä½ï¼ä½æ¯å¯¹å¤ä¸ªå
±äº«åéæä½æ¶ï¼CASæ¯æ æ³ä¿è¯æä½çååæ§çã
Javaä»1.5å¼å§JDKæä¾äºAtomicReferenceç±»æ¥ä¿è¯å¼ç¨å¯¹è±¡ä¹é´çååæ§ï¼å¯ä»¥æå¤ä¸ªåéæ¾å¨ä¸ä¸ªå¯¹è±¡éæ¥è¿è¡CASæä½ã
## å¹¶åå·¥å
·
å¨JDKçå¹¶åå
éæä¾äºå 个é常æç¨çå¹¶åå·¥å
·ç±»ãCountDownLatchãCyclicBarrieråSemaphoreå·¥å
·ç±»æä¾äºä¸ç§å¹¶åæµç¨æ§å¶çææ®µã
### CountDownLatch
CountDownLatchç¨äºæä¸ªçº¿ç¨çå¾
å
¶ä»çº¿ç¨**æ§è¡å®ä»»å¡**åæ§è¡ï¼ä¸thread.join()åè½ç±»ä¼¼ã常è§çåºç¨åºæ¯æ¯å¼å¯å¤ä¸ªçº¿ç¨åæ¶æ§è¡æä¸ªä»»å¡ï¼çå°ææä»»å¡æ§è¡å®åæ§è¡ç¹å®æä½ï¼å¦æ±æ»ç»è®¡ç»æã
```
public class CountDownLatchDemo {
static final int N = 4;
static CountDownLatch latch = new CountDownLatch(N);
public static void main(String[] args) throws InterruptedException {
for(int i = 0; i < N; i++) {
new Thread(new Thread1()).start();
}
latch.await(1000, TimeUnit.MILLISECONDS); //è°ç¨await()æ¹æ³ç线ç¨ä¼è¢«æèµ·ï¼å®ä¼çå¾
ç´å°countå¼ä¸º0æç»§ç»æ§è¡;çå¾
timeoutæ¶é´åcountå¼è¿æ²¡å为0çè¯å°±ä¼ç»§ç»æ§è¡
System.out.println("task finished");
}
static class Thread1 implements Runnable {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "starts working");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}
}
}
```
è¿è¡ç»æï¼
```java
Thread-0starts working
Thread-1starts working
Thread-2starts working
Thread-3starts working
task finished
```
### CyclicBarrier
CyclicBarrier(忥å±é)ï¼ç¨äºä¸ç»çº¿ç¨äºç¸çå¾
å°æä¸ªç¶æï¼ç¶åè¿ç»çº¿ç¨å**åæ¶**æ§è¡ã
```java
public CyclicBarrier(int parties, Runnable barrierAction) {
}
public CyclicBarrier(int parties) {
}
```
åæ°partiesæè®©å¤å°ä¸ªçº¿ç¨æè
ä»»å¡çå¾
è³æä¸ªç¶æï¼åæ°barrierAction为å½è¿äºçº¿ç¨é½è¾¾å°æä¸ªç¶ææ¶ä¼æ§è¡çå
容ã
```java
public class CyclicBarrierTest {
// 请æ±çæ°é
private static final int threadCount = 10;
// éè¦åæ¥ççº¿ç¨æ°é
private static final CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
public static void main(String[] args) throws InterruptedException {
// åå»ºçº¿ç¨æ±
ExecutorService threadPool = Executors.newFixedThreadPool(10);
for (int i = 0; i < threadCount; i++) {
final int threadNum = i;
Thread.sleep(1000);
threadPool.execute(() -> {
try {
test(threadNum);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
}
threadPool.shutdown();
}
public static void test(int threadnum) throws InterruptedException, BrokenBarrierException {
System.out.println("threadnum:" + threadnum + "is ready");
try {
/**çå¾
60ç§ï¼ä¿è¯å线ç¨å®å
¨æ§è¡ç»æ*/
cyclicBarrier.await(60, TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println("-----CyclicBarrierException------");
}
System.out.println("threadnum:" + threadnum + "is finish");
}
}
```
è¿è¡ç»æå¦ä¸ï¼å¯ä»¥çåºCyclicBarrieræ¯å¯ä»¥éç¨çï¼
```java
threadnum:0is ready
threadnum:1is ready
threadnum:2is ready
threadnum:3is ready
threadnum:4is ready
threadnum:4is finish
threadnum:3is finish
threadnum:2is finish
threadnum:1is finish
threadnum:0is finish
threadnum:5is ready
threadnum:6is ready
...
```
å½å个线ç¨é½å°è¾¾barrierç¶æåï¼ä¼ä»å个线ç¨ä¸éæ©ä¸ä¸ªçº¿ç¨å»æ§è¡Runnableã
### CyclicBarrieråCountDownLatchåºå«
CyclicBarrier å CountDownLatch é½è½å¤å®ç°çº¿ç¨ä¹é´ççå¾
ã
CountDownLatchç¨äºæä¸ªçº¿ç¨çå¾
å
¶ä»çº¿ç¨**æ§è¡å®ä»»å¡**åæ§è¡ãCyclicBarrierç¨äºä¸ç»çº¿ç¨äºç¸çå¾
å°æä¸ªç¶æï¼ç¶åè¿ç»çº¿ç¨å**åæ¶**æ§è¡ã
CountDownLatchç计æ°å¨åªè½ä½¿ç¨ä¸æ¬¡ï¼èCyclicBarrierç计æ°å¨å¯ä»¥ä½¿ç¨reset()æ¹æ³éç½®ï¼å¯ç¨äºå¤çæ´ä¸ºå¤æçä¸å¡åºæ¯ã
### Semaphore
Semaphore类似äºéï¼å®ç¨äºæ§å¶åæ¶è®¿é®ç¹å®èµæºççº¿ç¨æ°éï¼æ§å¶å¹¶åçº¿ç¨æ°ã
```
public class SemaphoreDemo {
public static void main(String[] args) {
final int N = 7;
Semaphore s = new Semaphore(3);
for(int i = 0; i < N; i++) {
new Worker(s, i).start();
}
}
static class Worker extends Thread {
private Semaphore s;
private int num;
public Worker(Semaphore s, int num) {
this.s = s;
this.num = num;
}
@Override
public void run() {
try {
s.acquire();
System.out.println("worker" + num + " using the machine");
Thread.sleep(1000);
System.out.println("worker" + num + " finished the task");
s.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
```
è¿è¡ç»æå¦ä¸ï¼å¯ä»¥çåºå¹¶éæç
§çº¿ç¨è®¿é®é¡ºåºè·åèµæºçéï¼å³
```java
worker0 using the machine
worker1 using the machine
worker2 using the machine
worker2 finished the task
worker0 finished the task
worker3 using the machine
worker4 using the machine
worker1 finished the task
worker6 using the machine
worker4 finished the task
worker3 finished the task
worker6 finished the task
worker5 using the machine
worker5 finished the task
```
## ååç±»
### åºæ¬ç±»åååç±»
使ç¨ååçæ¹å¼æ´æ°åºæ¬ç±»å
- AtomicIntegerï¼æ´åååç±»
- AtomicLongï¼é¿æ´åååç±»
- AtomicBoolean ï¼å¸å°åååç±»
AtomicInteger 类常ç¨çæ¹æ³ï¼
```java
public final int get() //è·åå½åçå¼
public final int getAndSet(int newValue)//è·åå½åçå¼ï¼å¹¶è®¾ç½®æ°çå¼
public final int getAndIncrement()//è·åå½åçå¼ï¼å¹¶èªå¢
public final int getAndDecrement() //è·åå½åçå¼ï¼å¹¶èªå
public final int getAndAdd(int delta) //è·åå½åçå¼ï¼å¹¶å ä¸é¢æçå¼
boolean compareAndSet(int expect, int update) //妿è¾å
¥çæ°å¼çäºé¢æå¼ï¼å以ååæ¹å¼å°è¯¥å¼è®¾ç½®ä¸ºè¾å
¥å¼ï¼updateï¼
public final void lazySet(int newValue)//æç»è®¾ç½®ä¸ºnewValue,ä½¿ç¨ lazySet 设置ä¹åå¯è½å¯¼è´å
¶ä»çº¿ç¨å¨ä¹åçä¸å°æ®µæ¶é´å
è¿æ¯å¯ä»¥è¯»å°æ§çå¼ã
```
AtomicInteger 类主è¦å©ç¨ CAS (compare and swap) ä¿è¯ååæä½ï¼ä»èé¿å
å éçé«å¼éã
### æ°ç»ç±»åååç±»
使ç¨ååçæ¹å¼æ´æ°æ°ç»éçæä¸ªå
ç´
- AtomicIntegerArrayï¼æ´å½¢æ°ç»ååç±»
- AtomicLongArrayï¼é¿æ´å½¢æ°ç»ååç±»
- AtomicReferenceArray ï¼å¼ç¨ç±»åæ°ç»ååç±»
AtomicIntegerArray ç±»å¸¸ç¨æ¹æ³ï¼
```java
public final int get(int i) //è·å index=i ä½ç½®å
ç´ çå¼
public final int getAndSet(int i, int newValue)//è¿å index=i ä½ç½®çå½åçå¼ï¼å¹¶å°å
¶è®¾ç½®ä¸ºæ°å¼ï¼newValue
public final int getAndIncrement(int i)//è·å index=i ä½ç½®å
ç´ çå¼ï¼å¹¶è®©è¯¥ä½ç½®çå
ç´ èªå¢
public final int getAndDecrement(int i) //è·å index=i ä½ç½®å
ç´ çå¼ï¼å¹¶è®©è¯¥ä½ç½®çå
ç´ èªå
public final int getAndAdd(int i, int delta) //è·å index=i ä½ç½®å
ç´ çå¼ï¼å¹¶å ä¸é¢æçå¼
boolean compareAndSet(int i, int expect, int update) //妿è¾å
¥çæ°å¼çäºé¢æå¼ï¼å以ååæ¹å¼å° index=i ä½ç½®çå
ç´ å¼è®¾ç½®ä¸ºè¾å
¥å¼ï¼updateï¼
public final void lazySet(int i, int newValue)//æç» å°index=i ä½ç½®çå
ç´ è®¾ç½®ä¸ºnewValue,ä½¿ç¨ lazySet 设置ä¹åå¯è½å¯¼è´å
¶ä»çº¿ç¨å¨ä¹åçä¸å°æ®µæ¶é´å
è¿æ¯å¯ä»¥è¯»å°æ§çå¼ã
```
### å¼ç¨ç±»åååç±»
- AtomicReferenceï¼å¼ç¨ç±»åååç±»
- AtomicStampedReferenceï¼å¸¦æçæ¬å·çå¼ç¨ç±»åååç±»ãè¯¥ç±»å°æ´æ°å¼ä¸å¼ç¨å
³èèµ·æ¥ï¼å¯ç¨äºè§£å³ååçæ´æ°æ°æ®åæ°æ®ççæ¬å·ï¼å¯ä»¥è§£å³ä½¿ç¨ CAS è¿è¡ååæ´æ°æ¶å¯è½åºç°ç ABA é®é¢ã
- AtomicMarkableReference ï¼ååæ´æ°å¸¦ææ è®°çå¼ç¨ç±»åãè¯¥ç±»å° boolean æ è®°ä¸å¼ç¨å
³èèµ·æ¥
## 为ä»ä¹è¦ä½¿ç¨Executorçº¿ç¨æ± æ¡æ¶å¢ï¼
- æ¯æ¬¡æ§è¡ä»»å¡é½éè¿new Thread()å»å建线ç¨ï¼æ¯è¾æ¶èæ§è½ï¼å建ä¸ä¸ªçº¿ç¨æ¯æ¯è¾èæ¶ãèèµæºç
- è°ç¨new Thread()å建ç线ç¨ç¼ºä¹ç®¡çï¼å¯ä»¥æ éå¶çå建ï¼çº¿ç¨ä¹é´çç¸äºç«äºä¼å¯¼è´è¿å¤å ç¨ç³»ç»èµæºè导è´ç³»ç»ç«çª
- ç´æ¥ä½¿ç¨new Thread()å¯å¨ç线ç¨ä¸å©äºæ©å±ï¼æ¯å¦å®æ¶æ§è¡ã宿æ§è¡ã宿¶å®ææ§è¡ã线ç¨ä¸æçé½ä¸å¥½å®ç°
## å¦ä½åæ¢ä¸ä¸ªæ£å¨è¿è¡ç线ç¨ï¼
1. 使ç¨å
±äº«åéçæ¹å¼ãå
±äº«åéå¯ä»¥è¢«å¤ä¸ªæ§è¡ç¸åä»»å¡ç线ç¨ç¨æ¥ä½ä¸ºæ¯å¦åæ¢çä¿¡å·ï¼éç¥åæ¢çº¿ç¨çæ§è¡ã
2. 使ç¨interruptæ¹æ³ç»æ¢çº¿ç¨ãå½ä¸ä¸ªçº¿ç¨è¢«é»å¡ï¼å¤äºä¸å¯è¿è¡ç¶ææ¶ï¼å³ä½¿ä¸»ç¨åºä¸å°è¯¥çº¿ç¨çå
±äº«åé设置为trueï¼ä½è¯¥çº¿ç¨æ¤æ¶æ ¹æ¬æ æ³æ£æ¥å¾ªç¯æ å¿ï¼å½ç¶ä¹å°±æ æ³ç«å³ä¸æãè¿æ¶åå¯ä»¥ä½¿ç¨Threadæä¾çinterrupt()æ¹æ³ï¼å ä¸ºè¯¥æ¹æ³è½ç¶ä¸ä¼ä¸æä¸ä¸ªæ£å¨è¿è¡ç线ç¨ï¼ä½æ¯å®å¯ä»¥ä½¿ä¸ä¸ªè¢«é»å¡ççº¿ç¨æåºä¸ä¸ªä¸æå¼å¸¸ï¼ä»èä½¿çº¿ç¨æåç»æé»å¡ç¶æã
## ä»ä¹æ¯Daemon线ç¨ï¼
åå°(daemon)线ç¨ï¼æ¯æå¨ç¨åºè¿è¡çæ¶åå¨åå°æä¾ä¸ç§éç¨æå¡ç线ç¨ï¼å¹¶ä¸è¿ä¸ªçº¿ç¨å¹¶ä¸å±äºç¨åºä¸ä¸å¯æç¼ºçé¨åãå æ¤ï¼å½ææçéåå°çº¿ç¨ç»ææ¶ï¼ç¨åºä¹å°±ç»æ¢äºï¼åæ¶ä¼ææ»è¿ç¨ä¸çææåå°çº¿ç¨ãåè¿æ¥è¯´ï¼åªè¦æä»»ä½éåå°çº¿ç¨è¿å¨è¿è¡ï¼ç¨åºå°±ä¸ä¼ç»æ¢ãå¿
é¡»å¨çº¿ç¨å¯å¨ä¹åè°ç¨setDaemon()æ¹æ³ï¼æè½æå®è®¾ç½®ä¸ºåå°çº¿ç¨ã
注æï¼åå°è¿ç¨å¨ä¸æ§è¡finallyåå¥çæ
åµä¸å°±ä¼ç»æ¢å
¶run()æ¹æ³ã
æ¯å¦ï¼JVMçåå¾åæ¶çº¿ç¨å°±æ¯Daemon线ç¨ï¼Finalizer乿¯å®æ¤çº¿ç¨ã
## SynchronizedMapåConcurrentHashMapæä»ä¹åºå«ï¼
SynchronizedMap䏿¬¡é使´å¼ 表æ¥ä¿è¯çº¿ç¨å®å
¨ï¼æä»¥æ¯æ¬¡åªè½æä¸ä¸ªçº¿ç¨æ¥è®¿é®mapã
JDK1.8 ConcurrentHashMapéç¨CASåsynchronizedæ¥ä¿è¯å¹¶åå®å
¨ãæ°æ®ç»æéç¨æ°ç»+é¾è¡¨/红é»äºåæ ãsynchronizedåªéå®å½åé¾è¡¨æçº¢é»äºåæ çé¦èç¹ï¼æ¯æå¹¶å访é®ãä¿®æ¹ã
å¦å¤ConcurrentHashMap使ç¨äºä¸ç§ä¸åçè¿ä»£æ¹å¼ãå½iterator被å建åéåååçæ¹åå°±ä¸åæ¯æåºConcurrentModificationExceptionï¼åè代ä¹çæ¯å¨æ¹åæ¶newæ°çæ°æ®ä»èä¸å½±ååæçæ°æ® ï¼iterator宿ååå°å¤´æéæ¿æ¢ä¸ºæ°çæ°æ® ï¼è¿æ ·iterator线ç¨å¯ä»¥ä½¿ç¨åæ¥èçæ°æ®ï¼èå线ç¨ä¹å¯ä»¥å¹¶åç宿æ¹åã
## æä¹å¤æçº¿ç¨æ± ç任塿¯ä¸æ¯æ§è¡å®äºï¼
æå ç§æ¹æ³ï¼
1ã使ç¨çº¿ç¨æ± çåç彿°**isTerminated()**;
executoræä¾ä¸ä¸ªåç彿°isTerminated()æ¥å¤æçº¿ç¨æ± ä¸ç任塿¯å¦å
¨é¨å®æã妿å
¨é¨å®æè¿åtrueï¼å¦åè¿åfalseã
2ã**使ç¨éå
¥éï¼ç»´æä¸ä¸ªå
Œ
±è®¡æ°**ã
ææçæ®éä»»å¡ç»´æä¸ä¸ªè®¡æ°å¨ï¼å½ä»»å¡å®ææ¶è®¡æ°å¨å ä¸ï¼è¿éè¦å éï¼ï¼å½è®¡æ°å¨çå¼çäºä»»å¡æ°æ¶ï¼è¿æ¶ææçä»»å¡å·²ç»æ§è¡å®æ¯äºã
3ã**使ç¨CountDownLatch**ã
å®çåçè·ç¬¬äºç§æ¹æ³ç±»ä¼¼ï¼ç»CountDownLatchä¸ä¸ªè®¡æ°å¼ï¼ä»»å¡æ§è¡å®æ¯åï¼è°ç¨countDown()æ§è¡è®¡æ°å¼åä¸ãæåæ§è¡çä»»å¡å¨è°ç¨æ¹æ³çå¼å§è°ç¨await()æ¹æ³ï¼è¿æ ·æ´ä¸ªä»»å¡ä¼é»å¡ï¼ç´å°è¿ä¸ªè®¡æ°å¼ä¸ºé¶ï¼æä¼ç»§ç»æ§è¡ã
è¿ç§æ¹å¼ç**缺ç¹**å°±æ¯éè¦æåç¥éä»»å¡çæ°éã
4ã**submitåçº¿ç¨æ± æäº¤ä»»å¡ï¼ä½¿ç¨Future夿任塿§è¡ç¶æ**ã
使ç¨submitåçº¿ç¨æ± æäº¤ä»»å¡ä¸executeæäº¤ä¸åï¼submit伿Futureç±»åçè¿åå¼ãéè¿future.isDone()æ¹æ³å¯ä»¥ç¥é任塿¯å¦æ§è¡å®æã
## ä»ä¹æ¯Futureï¼
å¨å¹¶åç¼ç¨ä¸ï¼ä¸ç®¡æ¯ç»§æ¿threadç±»è¿æ¯å®ç°runnableæ¥å£ï¼é½æ æ³ä¿è¯è·åå°ä¹åçæ§è¡ç»æãéè¿å®ç°Callbackæ¥å£ï¼å¹¶ç¨Futureå¯ä»¥æ¥æ¥æ¶å¤çº¿ç¨çæ§è¡ç»æã
Future表示ä¸ä¸ªå¯è½è¿æ²¡æå®æç弿¥ä»»å¡çç»æï¼é对è¿ä¸ªç»æå¯ä»¥æ·»å Callback以便å¨ä»»å¡æ§è¡æåæå¤±è´¥åä½åºç¸åºçæä½ã
举个ä¾åï¼æ¯å¦å»åæ©ç¹æ¶ï¼ç¹äºå
åååèï¼å
åéè¦ç3åéï¼åèåªé1åéï¼å¦ææ¯ä¸²è¡çä¸ä¸ªæ§è¡ï¼å¨å䏿©ç¹çæ¶åéè¦çå¾
4åéï¼ä½æ¯å ä¸ºä½ å¨çå
åçæ¶åï¼å¯ä»¥åæ¶åå¤åèï¼æä»¥å¨åå¤åèçè¿ç¨ä¸ï¼å¯ä»¥åæ¶åå¤å
åï¼è¿æ ·åªéè¦çå¾
3åéãFutureå°±æ¯åé¢è¿ç§æ§è¡æ¨¡å¼ã
Futureæ¥å£ä¸»è¦å
æ¬5ä¸ªæ¹æ³ï¼
1. get()æ¹æ³å¯ä»¥å½ä»»å¡ç»æåè¿åä¸ä¸ªç»æï¼å¦æè°ç¨æ¶ï¼å·¥ä½è¿æ²¡æç»æï¼åä¼é»å¡çº¿ç¨ï¼ç´å°ä»»å¡æ§è¡å®æ¯
2. get(long timeout,TimeUnit unit)åå¤çå¾
timeoutçæ¶é´å°±ä¼è¿åç»æ
3. cancel(boolean mayInterruptIfRunning)æ¹æ³å¯ä»¥ç¨æ¥åæ¢ä¸ä¸ªä»»å¡ï¼å¦æä»»å¡å¯ä»¥åæ¢ï¼éè¿mayInterruptIfRunningæ¥è¿è¡å¤æï¼ï¼åå¯ä»¥è¿åtrueï¼å¦æä»»å¡å·²ç»å®ææè
å·²ç»åæ¢ï¼æè
è¿ä¸ªä»»å¡æ æ³åæ¢ï¼åä¼è¿åfalseã
4. isDone()æ¹æ³å¤æå½åæ¹æ³æ¯å¦å®æ
5. isCancel()æ¹æ³å¤æå½åæ¹æ³æ¯å¦åæ¶
> åè龿¥ï¼https://blog.csdn.net/u014209205/article/details/80598209
