# ç®å认è¯å¹¶å
* [ç®å认è¯å¹¶å](#ç®å认è¯å¹¶å)
* [å¹¶åçå¤é¢æ§](#å¹¶åçå¤é¢æ§)
* [æ´å¿«çæ§è¡](#æ´å¿«çæ§è¡)
* [æ¹è¿ä»£ç ç设计](#æ¹è¿ä»£ç ç设计)
* [åºæ¬ççº¿ç¨æºå¶](#åºæ¬ççº¿ç¨æºå¶)
* [å®ä¹ä»»å¡](#å®ä¹ä»»å¡)
* [Thread ç±»](#thread-ç±»)
* [ä½¿ç¨ Executor](#使ç¨-executor)
* [CachedThreadPool](#cachedthreadpool)
* [FixedThreadPool](#fixedthreadpool)
* [SingleThreadExecutor](#singlethreadexecutor)
* [ä»ä»»å¡ä¸äº§çè¿åå¼](#ä»ä»»å¡ä¸äº§çè¿åå¼)
* [ä¼ç ](#ä¼ç )
* [ä¼å
级](#ä¼å
级)
* [ä½åºè®©æ¥](#ä½åºè®©æ¥)
* [åå°çº¿ç¨](#åå°çº¿ç¨)
* [ThreadFactory](#threadfactory)
* [å å
¥ä¸ä¸ªçº¿ç¨](#å å
¥ä¸ä¸ªçº¿ç¨)
* [线ç¨å¼å¸¸æè·](#线ç¨å¼å¸¸æè·)
å°ç®å为æ¢ï¼ä½ å¦å°ç齿¯é¡ºåºç¼ç¨ï¼é¡ºåºç¼ç¨çæ¦å¿µå°±æ¯æä¸æ¶å»åªæä¸ä¸ªä»»å¡å¨æ§è¡ï¼é¡ºåºç¼ç¨åºç¶è½å¤è§£å³å¾å¤é®é¢ï¼ä½æ¯å¯¹äºæç§ä»»å¡ï¼å¦æè½å¤å¹¶åçæ§è¡ç¨åºä¸éè¦çé¨åå°±æ¾å¾å°¤ä¸ºéè¦ï¼åæ¶ä¹å¯ä»¥æå¤§æé«ç¨åºè¿è¡æçï¼äº«åå¹¶åä¸ºä½ å¸¦æ¥ç便å©ã使¯ï¼çç»ææ¡å¹¶åç¼ç¨çè®ºåææ¯ï¼å¯¹äºåªä¼CRUDçä½ æ¥è¯´æ¯ä¸ç§åä½ åå¦é¢åå¯¹è±¡ä¸æ ·çä¸ç§é£è·ã
æ£å¦ä½ æçå°çï¼å½å¹¶è¡çä»»å¡å½¼æ¤å¹²æ¶æ¶ï¼å®é
çå¹¶åé®é¢å°±ä¼æ¥è¸µèè³ãèä¸å¹¶åé®é¢ä¸æ¯å¾é¾å¤ç°ï¼å¨ä½ å®é
çæµè¯è¿ç¨ä¸å¾å¾ä¼å¿½ç¥å®ä»¬ï¼å 为æ
鿝å¶å°åççï¼è¿ä¹æ¯æä»¬ç ç©¶å®ä»¬çå¿
è¦æ¡ä»¶ï¼å¦æä½ 对并åé®é¢ç½®ä¹ä¸çï¼é£ä¹ä½ æç»ä¼æ¿åå®ç»ä½ 带æ¥çæå®³ã
## å¹¶åçå¤é¢æ§
### æ´å¿«çæ§è¡
é度é®é¢å¬èµ·æ¥å¾ç®åï¼å¦æä½ æ³è®©ä¸ä¸ªç¨åºè¿è¡çæ´å¿«ä¸äºï¼é£ä¹å¯ä»¥å°å
¶åæå¤ä¸ªåçï¼å¨åç¬çå¤çå¨ä¸è¿è¡åèªçåçï¼åææ¯è¿äºä»»å¡å½¼æ¤ä¹é´æ²¡æèç³»ã
> 注æï¼é度çæé«æ¯ä»¥å¤æ ¸å¤çå¨è䏿¯è¯ççå½¢å¼åºç°çã
å¦æä½ æä¸å°å¤å¤çå¨çæºå¨ï¼é£ä¹ä½ å°±å¯ä»¥å¨è¿äºå¤çå¨ä¹é´åå¸å¤ä¸ªä»»å¡ï¼ä»èæå¤§çæé«ååéã**使¯ï¼å¹¶åéå¸¸æ¯æé«å¨åå¤çå¨ä¸çç¨åºçæ§è½ã**å¨åå¤çä¸çæ§è½å¼éè¦æ¯å¤å¤çå¨ä¸çæ§è½å¼é大å¾å¤ï¼å 为è¿å
¶ä¸å¢å äº`线ç¨åæ¢`(ä»ä¸ä¸ªçº¿ç¨åæ¢å°å¦å¤ä¸ä¸ªçº¿ç¨)çéè¦ä¾æ®ã表é¢ä¸çï¼å°ç¨åºçææé¨åå½ä½å个çä»»å¡è¿è¡å¥½åæ¯å¼éæ´å°ä¸ç¹ï¼èçäºçº¿ç¨åæ¢çæ¶é´ã
### æ¹è¿ä»£ç ç设计
å¨åCPUæºå¨ä¸ä½¿ç¨å¤ä»»å¡çç¨åºå¨ä»»ææ¶å»ä»æ§åªå¨æ§è¡ä¸é¡¹å·¥ä½ï¼ä½ èç¼è§å¯å°æ§å¶å°çè¾åºå¥½åæ¯è¿äºçº¿ç¨å¨åæ¶å·¥ä½ï¼è¿ä¸è¿æ¯CPUçéç¼æ³ç½¢äºï¼CPU为æ¯ä¸ªä»»å¡é½æä¾äºä¸åºå®çæ¶é´åçãJava ççº¿ç¨æºå¶æ¯æ¢å å¼çï¼ä¹å°±æ¯è¯´ï¼ä½ å¿
é¡»ç¼åæç§è®©æ¥è¯å¥æä¼è®©çº¿ç¨è¿è¡åæ¢ï¼åæ¢ç»å
¶ä»çº¿ç¨ã
## åºæ¬ççº¿ç¨æºå¶
å¹¶åç¼ç¨ä½¿æä»¬å¯ä»¥å°ç¨åºååæå¤ä¸ªå离çï¼ç¬ç«è¿è¡çä»»å¡ãéè¿ä½¿ç¨å¤çº¿ç¨æºå¶ï¼è¿äºç¬ç«ä»»å¡ä¸çæ¯ä¸é¡¹ä»»å¡é½ç±`æ§è¡çº¿ç¨`æ¥é©±å¨ãä¸ä¸ªçº¿ç¨å°±æ¯è¿ç¨ä¸çä¸ä¸ªåä¸çé¡ºåºæ§å¶æµãå æ¤ï¼å个è¿ç¨å¯ä»¥æ¥æå¤ä¸ªå¹¶åæ§è¡çä»»å¡ï¼ä½æ¯ä½ çç¨åºçèµ·æ¥æ¯ä¸ªä»»å¡é½æèªå·±çCPU䏿 ·ãå
¶åºå±æ¯ååCPUæ¶é´ï¼éå¸¸ä½ ä¸éè¦èèå®ã
### å®ä¹ä»»å¡
线ç¨å¯ä»¥é©±å¨ä»»å¡ï¼å æ¤ä½ éè¦ä¸ç§æè¿°ä»»å¡çæ¹å¼ï¼è¿å¯ä»¥ç± `Runnable` æ¥å£æ¥æä¾ï¼è¦æ³å®ä¹ä»»å¡ï¼åªéè¦å®ç° Runnable æ¥å£ï¼å¹¶å¨`run` æ¹æ³ä¸å®ç°ä½ çé»è¾å³å¯ã
```java
public class TestThread implements Runnable{
public static int i = 0;
@Override
public void run() {
System.out.println("start thread..." + i);
i++;
System.out.println("end thread ..." + i);
}
public static void main(String[] args) {
for(int i = 0;i < 5;i++){
TestThread testThread = new TestThread();
testThread.run();
}
}
}
```
ä»»å¡ run æ¹æ³ä¼ææç§å½¢å¼ç循ç¯ï¼ä½¿å¾ä»»å¡ä¸ç´è¿è¡ä¸å»ç´å°ä¸åéè¦ï¼æä»¥è¦è®¾å® run æ¹æ³çè·³åºæ¡ä»¶(æä¸ç§éæ©æ¯ä» run ä¸ç´æ¥è¿åï¼ä¸é¢ä¼è¯´å°ã)
å¨ run ä¸ä½¿ç¨éææ¹æ³ `Thread.yield() ` å¯ä»¥ä½¿ç¨çº¿ç¨è°åº¦ï¼å®çæææ¯å»ºè®®çº¿ç¨æºå¶è¿è¡åæ¢ï¼ä½ å·²ç»æ§è¡å®éè¦çé¨åäºï¼å©ä¸ç交ç»å
¶ä»çº¿ç¨è·ä¸è·å§ãæ³¨ææ¯å»ºè®®æ§è¡ï¼è䏿¯å¼ºå¶æ§è¡ãå¨ä¸é¢æ·»å Thread.yield() ä½ ä¼çå°æææçè¾åº
```java
public void run() {
System.out.println("start thread..." + i);
i++;
Thread.yield();
System.out.println("end thread ..." + i);
}
```
### Thread ç±»
å° Runnable 转å工使¹å¼çä¼ ç»æ¹å¼æ¯ä½¿ç¨ Thread ç±»æç®¡ä»ï¼ä¸é¢å±ç¤ºäºä½¿ç¨ Thread ç±»æ¥å®ç°ä¸ä¸ªçº¿ç¨ã
```java
public static void main(String[] args) {
for(int i = 0;i < 5;i++){
Thread t = new Thread(new TestThread());
t.start();
}
System.out.println("Waiting thread ...");
}
```
Thread æé å¨åªéè¦ä¸ä¸ª Runnable 对象ï¼è°ç¨ Thread 对象ç start() æ¹æ³ä¸ºè¯¥çº¿ç¨æ§è¡å¿
é¡»çåå§åæä½ï¼ç¶åè°ç¨ Runnable ç run æ¹æ³ï¼ä»¥ä¾¿å¨è¿ä¸ªçº¿ç¨ä¸å¯å¨ä»»å¡ãå¯ä»¥çå°ï¼å¨ run æ¹æ³è¿æ²¡æç»æåï¼run 就被è¿åäºãä¹å°±æ¯è¯´ï¼ç¨åºä¸ä¼çå° run æ¹æ³æ§è¡å®æ¯å°±ä¼æ§è¡ä¸é¢çæä»¤ã
å¨ run æ¹æ³ä¸æå°åºæ¯ä¸ªçº¿ç¨çååï¼å°±æ´è½çå°ä¸åç线ç¨ç忢åè°åº¦
```java
@Override
public void run() {
System.out.println(Thread.currentThread() + "start thread..." + i);
i++;
System.out.println(Thread.currentThread() + "end thread ..." + i);
}
```
è¿ç§çº¿ç¨åæ¢åè°åº¦æ¯äº¤ç± `线ç¨è°åº¦å¨` æ¥èªå¨æ§å¶çï¼å¦æä½ çæºå¨ä¸æå¤ä¸ªå¤çå¨ï¼çº¿ç¨è°åº¦å¨ä¼å¨è¿äºå¤çå¨ä¹é´é»é»çåå线ç¨ãæ¯ä¸æ¬¡çè¿è¡ç»æé½ä¸å°½ç¸åï¼å 为线ç¨è°åº¦æºå¶æ¯æªç¡®å®çã
### ä½¿ç¨ Executor
#### CachedThreadPool
JDK1.5 ç**java.util.concurrent** å
ä¸çæ§è¡å¨ **Executor** å°ä¸ºä½ 管ç Thread 对象ï¼ä»èç®åäºå¹¶åç¼ç¨ãExecutor å¨å®¢æ·ç«¯åä»»å¡ä¹é´æä¾äºä¸ä¸ªé´æ¥å±ï¼ä¸å®¢æ·ç«¯ç´æ¥æ§è¡ä»»å¡ä¸åï¼è¿ä¸ªä¸ä»å¯¹è±¡å°æ§è¡ä»»å¡ãExecutor å
è®¸ä½ ç®¡ç弿¥ä»»å¡çæ§è¡ï¼èæ é¡»æ¾ç¤ºå°ç®¡ç线ç¨ççå½å¨æã
```java
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
for(int i = 0;i < 5;i++){
service.execute(new TestThread());
}
service.shutdown();
}
```
æä»¬ä½¿ç¨ Executor æ¥æ¿ä»£ä¸è¿°æ¾ç¤ºå建 Thread 对象ã`CachedThreadPool` 为æ¯ä¸ªä»»å¡é½å建ä¸ä¸ªçº¿ç¨ã注æï¼ExecutorService 对象æ¯ä½¿ç¨éæç `Executors` å建çï¼è¿ä¸ªæ¹æ³å¯ä»¥ç¡®å® Executor ç±»åã对 `shutDown` çè°ç¨å¯ä»¥é²æ¢æ°ä»»å¡æäº¤ç» ExecutorService ï¼è¿ä¸ªçº¿ç¨å¨ Executor 䏿æä»»å¡å®æåéåºã
#### FixedThreadPool
FixedThreadPool ä½¿ä½ å¯ä»¥ä½¿ç¨æéç线ç¨éæ¥å¯å¨å¤çº¿ç¨
```java
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(5);
for(int i = 0;i < 5;i++){
service.execute(new TestThread());
}
service.shutdown();
}
```
æäº FixedThreadPool ä½¿ä½ å¯ä»¥ä¸æ¬¡æ§çé¢å
æ§è¡é«æç线ç¨åé
ï¼å æ¤ä¹å°±å¯ä»¥éå¶çº¿ç¨çæ°éãè¿å¯ä»¥èçæ¶é´ï¼å ä¸ºä½ ä¸å¿
为æ¯ä¸ªä»»å¡é½åºå®çä»åºå建线ç¨çå¼éã
#### SingleThreadExecutor
SingleThreadExecutor å°±æ¯çº¿ç¨æ°é为 1 ç FixedThreadPoolï¼å¦æå SingleThreadPool 䏿¬¡æ§æäº¤äºå¤ä¸ªä»»å¡ï¼é£ä¹è¿äºä»»å¡å°ä¼æéï¼æ¯ä¸ªä»»å¡é½ä¼å¨ä¸ä¸ä¸ªä»»å¡å¼å§åç»æï¼ææçä»»å¡é½å°ä½¿ç¨ç¸åç线ç¨ãSingleThreadPool ä¼åºååæææäº¤ç»ä»çä»»å¡ï¼å¹¶ä¼ç»´æ¤å®èªå·±(éè)çæ¬æéåã
```java
public static void main(String[] args) {
ExecutorService service = Executors.newSingleThreadExecutor();
for(int i = 0;i < 5;i++){
service.execute(new TestThread());
}
service.shutdown();
}
```
ä»è¾åºçç»æå°±å¯ä»¥çå°ï¼ä»»å¡é½æ¯æ¨çæ§è¡çãæä¸ºä»»å¡åé
äºäºä¸ªçº¿ç¨ï¼ä½æ¯è¿äºä¸ªçº¿ç¨ä¸åæ¯æä»¬ä¹åçå°çææ¢è¿æ¢åºçææï¼å®æ¯æ¬¡é½ä¼å
æ§è¡å®èªå·±çé£ä¸ªçº¿ç¨ï¼ç¶åä½ä¸ç线ç¨ç»§ç»âèµ°å®âè¿æ¡çº¿ç¨çæ§è¡è·¯å¾ãä½ å¯ä»¥ç¨ SingleThreadExecutor æ¥ç¡®ä¿ä»»ææ¶å»é½åªæå¯ä¸ä¸ä¸ªä»»å¡å¨è¿è¡ã
### ä»ä»»å¡ä¸äº§çè¿åå¼
Runnable æ¯æ§è¡å·¥ä½çç¬ç«ä»»å¡ï¼ä½å®ä¸è¿åä»»ä½å¼ãå¦æä½ å¸æä»»å¡å¨å®ææ¶è½å¤è¿åä¸ä¸ªå¼ ï¼è¿ä¸ªæ¶åä½ å°±éè¦èèä½¿ç¨ `Callable` æ¥å£ï¼å®æ¯ JDK1.5 ä¹åå¼å
¥çï¼éè¿è°ç¨å®ç `submit` æ¹æ³ï¼å¯ä»¥æå®çè¿å弿¾å¨ä¸ä¸ª Future 对象ä¸ï¼ç¶åæ ¹æ®ç¸åºç get() æ¹æ³åå¾æäº¤ä¹åçè¿åå¼ã
```java
public class TaskWithResult implements Callable {
private int id;
public TaskWithResult(int id){
this.id = id;
}
@Override
public String call() throws Exception {
return "result of TaskWithResult " + id;
}
}
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executors = Executors.newCachedThreadPool();
ArrayList> future = new ArrayList<>();
for(int i = 0;i < 10;i++){
// è¿åçæ¯è°ç¨ call æ¹æ³çç»æ
future.add(executors.submit(new TaskWithResult(i)));
}
for(Future fs : future){
System.out.println(fs.get());
}
}
}
```
submit() æ¹æ³ä¼è¿å Future 对象ï¼Future 对象åå¨çä¹å°±æ¯ä½ è¿åçç»æãä½ ä¹å¯ä»¥ä½¿ç¨ `isDone` æ¥æ¥è¯¢ Future æ¯å¦å·²ç»å®æã
### ä¼ç
å½±åä»»å¡è¡ä¸ºçä¸ç§ç®åæ¹å¼å°±æ¯ä½¿çº¿ç¨ ä¼ç ï¼éå®ç»å®çä¼ç æ¶é´ï¼è°ç¨å®ç `sleep()` æ¹æ³ï¼ ä¸è¬ä½¿ç¨ç`TimeUnit` è¿ä¸ªæ¶é´ç±»æ¿æ¢ `Thread.sleep()` æ¹æ³ï¼ç¤ºä¾å¦ä¸ï¼
```java
public class SuperclassThread extends TestThread{
@Override
public void run() {
System.out.println(Thread.currentThread() + "starting ..." );
try {
for(int i = 0;i < 5;i++){
if(i == 3){
System.out.println(Thread.currentThread() + "sleeping ...");
TimeUnit.MILLISECONDS.sleep(1000);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "wakeup and end ...");
}
public static void main(String[] args) {
ExecutorService executors = Executors.newCachedThreadPool();
for(int i = 0;i < 5;i++){
executors.execute(new SuperclassThread());
}
executors.shutdown();
}
}
```
> å
³äº TimeUnit ä¸ç sleep() æ¹æ³å Thread.sleep() æ¹æ³çæ¯è¾ï¼è¯·åèä¸é¢è¿ç¯å客
>
> (https://www.cnblogs.com/xiadongqing/p/9925567.html)
### ä¼å
级
ä¸é¢æå°çº¿ç¨è°åº¦å¨å¯¹æ¯ä¸ªçº¿ç¨çæ§è¡é½æ¯ä¸å¯é¢ç¥çï¼éæºæ§è¡çï¼é£ä¹ææ²¡æåæ³åè¯çº¿ç¨è°åº¦å¨åªä¸ªä»»å¡æ³è¦ä¼å
被æ§è¡å¢ï¼ä½ å¯ä»¥éè¿è®¾ç½®çº¿ç¨çä¼å
çº§ç¶æï¼åè¯çº¿ç¨è°åº¦å¨åªä¸ªçº¿ç¨çæ§è¡ä¼å
级æ¯è¾é«ï¼"请ç»è¿ä¸ªéªæé©¬ä¸æ´¾å"ï¼çº¿ç¨è°åº¦å¨å¾åäºè®©ä¼å
级è¾é«ç线ç¨ä¼å
æ§è¡ï¼ç¶èï¼è¿å¹¶ä¸æå³çä¼å
级ä½ç线ç¨å¾ä¸å°æ§è¡ï¼ä¹å°±æ¯è¯´ï¼ä¼å
级ä¸ä¼å¯¼è´æ»éçé®é¢ãä¼å
级è¾ä½ç线ç¨åªæ¯æ§è¡é¢çè¾ä½ã
```java
public class SimplePriorities implements Runnable{
private int priority;
public SimplePriorities(int priority) {
this.priority = priority;
}
@Override
public void run() {
Thread.currentThread().setPriority(priority);
for(int i = 0;i < 100;i++){
System.out.println(this);
if(i % 10 == 0){
Thread.yield();
}
}
}
@Override
public String toString() {
return Thread.currentThread() + " " + priority;
}
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
for(int i = 0;i < 5;i++){
service.execute(new SimplePriorities(Thread.MAX_PRIORITY));
}
service.execute(new SimplePriorities(Thread.MIN_PRIORITY));
}
}
```
toString() æ¹æ³è¢«è¦çï¼ä»¥ä¾¿éè¿ä½¿ç¨ `Thread.toString()` æ¹æ³æ¥æå°çº¿ç¨çåç§°ãä½ å¯ä»¥æ¹å线ç¨çé»è®¤è¾åºï¼è¿ééç¨äº **Thread[pool-1-thread-1,10,main]** è¿ç§å½¢å¼çè¾åºã
éè¿è¾åºï¼ä½ å¯ä»¥çå°ï¼æåä¸ä¸ªçº¿ç¨çä¼å
级æä½ï¼å
¶ä½ç线ç¨ä¼å
级æé«ã注æï¼ä¼å
级æ¯å¨ run å¼å¤´è®¾ç½®çï¼å¨æé å¨ä¸è®¾ç½®å®ä»¬ä¸ä¼æä»»ä½å¥½å¤ï¼å 为è¿ä¸ªæ¶å线ç¨è¿æ²¡ææ§è¡ä»»å¡ã
尽管JDKæ10个ä¼å
级ï¼ä½æ¯ä¸è¬åªæ**MAX_PRIORITYï¼NORM_PRIORITYï¼MIN_PRIORITY** ä¸ç§çº§å«ã
### ä½åºè®©æ¥
æä»¬ä¸é¢æè¿ï¼å¦æç¥éä¸ä¸ªçº¿ç¨å·²ç»å¨ run() æ¹æ³ä¸è¿è¡çå·®ä¸å¤äºï¼é£ä¹å®å°±å¯ä»¥ç»çº¿ç¨è°åº¦å¨ä¸ä¸ªæç¤ºï¼æå·²ç»å®æäºä»»å¡ä¸æéè¦çé¨åï¼å¯ä»¥è®©ç»å«ç线ç¨ä½¿ç¨CPUäºãè¿ä¸ªæç¤ºå°éè¿ yield() æ¹æ³ä½åºã
> æä¸ä¸ªå¾éè¦çç¹å°±æ¯ï¼Thread.yield() æ¯å»ºè®®æ§è¡åæ¢CPUï¼è䏿¯å¼ºå¶æ§è¡CPU忢ã
对äºä»»ä½éè¦çæ§å¶æè
å¨è°ç¨åºç¨æ¶ï¼é½ä¸è½ä¾èµäº `yield() `æ¹æ³ï¼å®é
ä¸ï¼ yield() æ¹æ³ç»å¸¸è¢«æ»¥ç¨ã
### åå°çº¿ç¨
åå°(daemon) 线ç¨ï¼æ¯æè¿è¡æ¶å¨åå°æä¾çä¸ç§æå¡çº¿ç¨ï¼è¿ç§çº¿ç¨ä¸æ¯å±äºå¿
é¡»çã彿æéåå°çº¿ç¨ç»ææ¶ï¼ç¨åºä¹å°±åæ¢äºï¼**åæ¶ä¼ç»æ¢ææçåå°çº¿ç¨ã**åè¿æ¥è¯´ï¼åªè¦æä»»ä½éåå°çº¿ç¨è¿å¨è¿è¡ï¼ç¨åºå°±ä¸ä¼ç»æ¢ã
```java
public class SimpleDaemons implements Runnable{
@Override
public void run() {
while (true){
try {
TimeUnit.MILLISECONDS.sleep(100);
System.out.println(Thread.currentThread() + " " + this);
} catch (InterruptedException e) {
System.out.println("sleep() interrupted");
}
}
}
public static void main(String[] args) throws InterruptedException {
for(int i = 0;i < 10;i++){
Thread daemon = new Thread(new SimpleDaemons());
daemon.setDaemon(true);
daemon.start();
}
System.out.println("All Daemons started");
TimeUnit.MILLISECONDS.sleep(175);
}
}
```
卿¯æ¬¡ç循ç¯ä¸ä¼å建10个线ç¨ï¼å¹¶ææ¯ä¸ªçº¿ç¨è®¾ç½®ä¸ºåå°çº¿ç¨ï¼ç¶åå¼å§è¿è¡ï¼for循ç¯ä¼è¿è¡å次ï¼ç¶åè¾åºä¿¡æ¯ï¼éå主线ç¨ç¡ç 䏿®µæ¶é´å忢è¿è¡ã卿¯æ¬¡run 循ç¯ä¸ï¼é½ä¼æå°å½å线ç¨çä¿¡æ¯ï¼ä¸»çº¿ç¨è¿è¡å®æ¯ï¼ç¨åºå°±æ§è¡å®æ¯äºãå 为 `daemon` æ¯åå°çº¿ç¨ï¼æ æ³å½±å主线ç¨çæ§è¡ã
使¯å½ä½ æ `daemon.setDaemon(true)` 廿æ¶ï¼while(true) ä¼è¿è¡æ é循ç¯ï¼é£ä¹ä¸»çº¿ç¨ä¸ç´å¨æ§è¡æéè¦çä»»å¡ï¼æä»¥ä¼ä¸ç´å¾ªç¯ä¸å»æ æ³åæ¢ã
### ThreadFactory
æéè¦å建线ç¨ç对象ã使ç¨çº¿ç¨å·¥åæ¿æ¢äº Thread æè
Runnable æ¥å£çç¡¬è¿æ¥ï¼ä½¿ç¨åºè½å¤ä½¿ç¨ç¹æ®ç线ç¨åç±»ï¼ä¼å
级çãä¸è¬çå建æ¹å¼ä¸º
```java
class SimpleThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
return new Thread(r);
}
}
```
> Executors.defaultThreadFactory æ¹æ³æä¾äºä¸ä¸ªæ´æç¨çç®åå®ç°ï¼å®å¨è¿åä¹åå°å建ç线ç¨ä¸ä¸æè®¾ç½®ä¸ºå·²ç¥å¼
ThreadFactory æ¯ä¸ä¸ªæ¥å£ï¼å®åªæä¸ä¸ªæ¹æ³å°±æ¯å建线ç¨çæ¹æ³
```java
public interface ThreadFactory {
// æå»ºä¸ä¸ªæ°ç线ç¨ãå®ç°ç±»å¯è½åå§åä¼å
级ï¼åç§°ï¼åå°çº¿ç¨ç¶æå 线ç¨ç»ç
Thread newThread(Runnable r);
}
```
ä¸é¢æ¥çä¸ä¸ª ThreadFactory çä¾å
```java
public class DaemonThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
}
public class DaemonFromFactory implements Runnable{
@Override
public void run() {
while (true){
try {
TimeUnit.MILLISECONDS.sleep(100);
System.out.println(Thread.currentThread() + " " + this);
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newCachedThreadPool(new DaemonThreadFactory());
for(int i = 0;i < 10;i++){
service.execute(new DaemonFromFactory());
}
System.out.println("All daemons started");
TimeUnit.MILLISECONDS.sleep(500);
}
}
```
`Executors.newCachedThreadPool` å¯ä»¥æ¥åä¸ä¸ªçº¿ç¨æ± 对象ï¼å建ä¸ä¸ªæ ¹æ®éè¦å建æ°çº¿ç¨ççº¿ç¨æ± ï¼ä½ä¼å¨å®ä»¬å¯ç¨æ¶éç¨å
åæé ç线ç¨ï¼å¹¶å¨éè¦æ¶ä½¿ç¨æä¾çThreadFactoryå建æ°çº¿ç¨ã
```java
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue(),
threadFactory);
}
```
### å å
¥ä¸ä¸ªçº¿ç¨
ä¸ä¸ªçº¿ç¨å¯ä»¥å¨å
¶ä»çº¿ç¨ä¸è°ç¨ `join()` æ¹æ³ï¼å
¶æææ¯çå¾
䏿®µæ¶é´ç´å°ç¬¬äºä¸ªçº¿ç¨ç»æææ£å¸¸æ§è¡ã妿æä¸ªçº¿ç¨å¨å¦ä¸ä¸ªçº¿ç¨ t ä¸è°ç¨ t.join() æ¹æ³ï¼æ¤çº¿ç¨å°è¢«æèµ·ï¼ç´å°ç®æ çº¿ç¨ t ç»ææåå¤(å¯ä»¥ç¨ t.isAlive() è¿å为çå夿)ã
ä¹å¯ä»¥å¨è°ç¨ join æ¶å¸¦ä¸ä¸ä¸ªè¶
æ¶åæ°ï¼æ¥è®¾ç½®å°ææ¶é´ï¼æ¶é´å°æï¼joinæ¹æ³èªå¨è¿åã
对 join çè°ç¨ä¹å¯ä»¥è¢«ä¸æï¼åæ³æ¯å¨çº¿ç¨ä¸è°ç¨ `interrupted` æ¹æ³ï¼è¿æ¶éè¦ç¨å° try...catch åå¥
```java
public class TestJoinMethod extends Thread{
@Override
public void run() {
for(int i = 0;i < 5;i++){
try {
TimeUnit.MILLISECONDS.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Interrupted sleep");
}
System.out.println(Thread.currentThread() + " " + i);
}
}
public static void main(String[] args) throws InterruptedException {
TestJoinMethod join1 = new TestJoinMethod();
TestJoinMethod join2 = new TestJoinMethod();
TestJoinMethod join3 = new TestJoinMethod();
join1.start();
// join1.join();
join2.start();
join3.start();
}
}
```
join() æ¹æ³çå¾
çº¿ç¨æ»äº¡ã æ¢å¥è¯è¯´ï¼å®ä¼å¯¼è´å½åè¿è¡ç线ç¨åæ¢æ§è¡ï¼ç´å°å®å å
¥ç线ç¨å®æå
¶ä»»å¡ã
### 线ç¨å¼å¸¸æè·
ç±äºçº¿ç¨çæ¬è´¨ï¼ä½¿ä½ ä¸è½æè·ä»çº¿ç¨ä¸éé¸çå¼å¸¸ï¼ä¸æ¦å¼å¸¸éåºä»»å¡çrun æ¹æ³ï¼å®å°±ä¼åå¤ä¼ æå°æ§å¶å°ï¼é¤éä½ éåç¹æ®çæ¥éª¤æè·è¿ç§é误çå¼å¸¸ï¼å¨ Java5 ä¹åï¼ä½ å¯ä»¥éè¿çº¿ç¨ç»æ¥æè·ï¼ä½æ¯å¨ Java5 ä¹åï¼å°±éè¦ç¨ Executor æ¥è§£å³é®é¢ï¼å 为线ç¨ç»ä¸æ¯ä¸æ¬¡å¥½çå°è¯ã
ä¸é¢çä»»å¡ä¼å¨ run æ¹æ³çæ§è¡æé´æåºä¸ä¸ªå¼å¸¸ï¼å¹¶ä¸è¿ä¸ªå¼å¸¸ä¼æå° run æ¹æ³çå¤é¢ï¼èä¸ main æ¹æ³æ æ³å¯¹å®è¿è¡æè·
```java
public class ExceptionThread implements Runnable{
@Override
public void run() {
throw new RuntimeException();
}
public static void main(String[] args) {
try {
ExecutorService service = Executors.newCachedThreadPool();
service.execute(new ExceptionThread());
}catch (Exception e){
System.out.println("eeeee");
}
}
}
```
为äºè§£å³è¿ä¸ªé®é¢ï¼æä»¬éè¦ä¿®æ¹ Executor 产ç线ç¨çæ¹å¼ï¼Java5 æä¾äºä¸ä¸ªæ°çæ¥å£ `Thread.UncaughtExceptionHandler` ï¼å®å
è®¸ä½ å¨æ¯ä¸ª Thread ä¸é½éçä¸ä¸ªå¼å¸¸å¤çå¨ã`Thread.UncaughtExceptionHandler.uncaughtException()` ä¼å¨çº¿ç¨å æªæè·ä¸´è¿æ»äº¡æ¶è¢«è°ç¨ã
```java
public class ExceptionThread2 implements Runnable{
@Override
public void run() {
Thread t = Thread.currentThread();
System.out.println("run() by " + t);
System.out.println("eh = " + t.getUncaughtExceptionHandler());
// æå¨æåºå¼å¸¸
throw new RuntimeException();
}
}
// å®ç°Thread.UncaughtExceptionHandler æ¥å£ï¼å建å¼å¸¸å¤çå¨
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("caught " + e);
}
}
public class HandlerThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
System.out.println(this + " creating new Thread");
Thread t = new Thread(r);
System.out.println("created " + t);
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
System.out.println("ex = " + t.getUncaughtExceptionHandler());
return t;
}
}
public class CaptureUncaughtException {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool(new HandlerThreadFactory());
service.execute(new ExceptionThread2());
}
}
```
å¨ç¨åºä¸æ·»å äºé¢å¤ç追踪æºå¶ï¼ç¨æ¥éªè¯å·¥åå建ç线ç¨ä¼ä¼ éç»`UncaughtExceptionHandler`ï¼ä½ å¯ä»¥çå°ï¼æªæè·çå¼å¸¸æ¯éè¿ `uncaughtException ` æ¥æè·çã

