# 1、線程池
### 1 為什么要使用線程池
平常使用new Thread(). start( ) 的方式啟動的線程,使用完之后就會變成垃圾,被系統銷毀掉;如果在任務眾多的情況下頻繁的開啟和銷毀線程,就會給系統造成極大的壓力;而使用線程池則會對線程進行統一的管理,一個線程在執行完任務后不會被系統回收,而是可以繼續執行下一個任務,不會造成線程的頻繁啟動和銷毀,減輕了系統的壓力。
### 2 Java中的線程池
#### 1 ThreadPoolExecutor 基本線程池
~~~
public ThreadPoolExecutor(int corePoolSize, //該線程池中的核心線程數量
int maximumPoolSize, //該線程中的最大線程數量
long keepAliveTime, //該線程的非核心線程的存活時間(可設置allowCoreThreadTimeOut=true,使超時時間適用于核心線程)
TimeUnit unit, //存活時間的單位 有:納秒,毫秒,微秒,秒,分支,小時,天
BlockingQueue<Runnable> workQueue, //任務隊列
ThreadFactory threadFactory, //線程工程,可用于設置線程的名字等屬性,一般不使用
RejectedExecutionHandler handler //
) {
...
}
~~~
#### 2 線程池的執行策略
當execute( ) 一個任務時:
1. 當**核心線程未滿時**,直接啟動一個空閑的核心線程去執行任務;
2. 當**核心線程已滿而任務隊列未滿時**,則將任務放在任務隊列中,等待某個核心線程執行完任務后執行該任務;
3. 當**核心線程已滿并且任務隊列也已經滿了時**,則啟動一個空閑的非核心線程去執行任務;
4. 當**三者(核心線程,任務隊列,非核心線程,也可以是最大線程數量和任務隊列)均已滿**,則會采取飽和策略,拒絕執行該任務,拋出異常 java.util.concurrent.RejectedExecutionException
#### 3 Java中內置的線程池
* **FixedThreadPool( )**
線程數量固定,且全部為核心線程,阻塞隊列無界
**適用:執行長期的任務,性能較好**
~~~
//源碼
public static ExecutorService newFixedThreadPool(int coreSize) {
return new ThreadPoolExecutor(coreSize, coreSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
}
//創建fixed線程池
final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
fixedThreadPool.execute(runnable);
~~~
* **CachedThreadPool( )**
沒有核心線程,全部為非核心線程,最大線程數量為Integer.MAX\_VALUE,線程存活時間為60s
**適用:執行很多短期異步的小程序或者負載較輕的服務器**
~~~
//源碼
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue());
}
//創建Cached線程池
final ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
cachedThreadPool.execute(runnable);
~~~
* **ScheduledThreadPool( )**
定時延時執行
**適用:周期性執行任務的場景**
~~~
//源碼
public static ScheduledExecutorService newScheduledThreadPool(int coreSize) {
return new ScheduledThreadPoolExecutor(coreSize);
}
//創建Scheduled線程池
final ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
scheduledThreadPool.schedule(runnable,10,TimeUnit.SECONDS);//延遲啟動任務
scheduledThreadPool.scheduleAtFixedRate(runnable,5,1,TimeUnit.SECONDS);//延遲5s后啟動,每1s執行一次
scheduledThreadPool.scheduleWithFixedDelay(runnable,5,1,TimeUnit.SECONDS);//啟動后第一次延遲5s執行,后面延遲1s執行
~~~
* **SingleThreadPool( )**
線程池中只要一個核心任務
**適用:一個任務一個任務執行的場景**
~~~
//源碼
public static ExecutorService newSingleThreadExecutor() {
return new Executors.FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));
}
//創建Single線程池
final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
singleThreadExecutor.execute(runnable);
~~~
* **SingleScheduledThreadPool( )**
只有一個核心線程的延時任務
~~~
//源碼
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new Executors.DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1));
}
~~~
| | |
| --- | --- |
| | |
### 3 Java中的阻塞隊列
| **隊列名稱** | **描述** |
| --- | --- |
| **ArrayBlockingQueue** | **一個由數組結構組成的有界阻塞隊列。** |
| **LinkedBlockingQueue** | **一個由鏈表結構組成的有界阻塞隊列。** |
| **PriorityBlockingQueue** | **一個支持優先級排序的無界阻塞隊列。** |
| **DelayQueue** | **一個使用優先級隊列實現的無界阻塞隊列。** |
| **SynchronousQueue** | **一個不存儲元素的阻塞隊列。** |
| **LinkedTransferQueue**| **一個由鏈表結構組成的無界阻塞隊列。** |
| **LinkedBlockingDeque** | **一個由鏈表結構組成的雙向阻塞隊列。** |