為了解決執行服務的生命周期問題,Executor擴展了ExecutorService接口;
ExecutorService的生命周期有三種狀態:運行、關閉和已終止;
### 主要API
* shutdown\(\):執行平緩關閉流程
* shutdownNow\(\):立即關閉
* awaitTermination\(\)
* invokeAll\(\)
#### **shutdown\(\)**
將線程池狀態置為SHUTDOWN,并不會立即停止:
* 停止接收外部submit的任務
* 內部正在跑的任務和隊列里等待的任務,會執行完
* 等到第二步完成后,才真正停止
#### **shutdownNow\(\)**
將線程池狀態置為STOP。企圖立即停止,事實上不一定:
* 跟shutdown\(\)一樣,先停止接收外部提交的任務
* 忽略隊列里等待的任務
* 嘗試將正在跑的任務interrupt中斷
* 返回未執行的任務列表
> 它試圖終止線程的方法是通過調用Thread.interrupt\(\)方法來實現的,但是大家知道,這種方法的作用有限,如果線程中沒有sleep 、wait、Condition、定時鎖等應用, interrupt\(\)方法是無法中斷當前的線程的。所以,ShutdownNow\(\)并不代表線程池就一定立即就能退出,它也可能必須要等待所有正在執行的任務都執行完成了才能退出。但是大多數時候是能立即退出的
shuntdownNow返回的Runnable對象可能與提交的Runnable對象并不相同;它們可能是被封裝過的已提交的任務;
#### awaitTermination\(long timeOut, TimeUnit unit\)
當前線程阻塞,直到
* 等所有已提交的任務(包括正在跑的和隊列中等待的)執行完
* 或者等超時時間到
* 或者線程被中斷,拋出InterruptedException
然后返回true(shutdown請求后所有任務執行完畢)或false(已超時)
> shuntdown\(\)和awaitTermination\(\)效果差不多,方法執行之后,都要等到提交的任務全部執行完才停
#### shutdown\(\)&&shutdownNow\(\)
shutdownNow\(\)能立即停止線程池,正在跑的和正在等待的任務都停下了。這樣做立即生效,但是風險也比較大;
shutdown\(\)只是關閉了提交通道,用submit\(\)是無效的;而內部該怎么跑還是怎么跑,跑完再停
#### shutdown\(\)&&awaitTermination\(\)
shutdown\(\)后,不能再提交新的任務進去;但是awaitTermination\(\)后,可以繼續提交。
awaitTermination\(\)是阻塞的,返回結果是線程池是否已停止(true/false);shutdown\(\)不阻塞
【知識點】
* 優雅的關閉,用shutdown\(\)
* 想立馬關閉,并得到未執行任務列表,用shutdownNow\(\)
* 優雅的關閉,并允許關閉聲明后新任務能提交,用awaitTermination\(\)
關閉功能【從強到弱】依次是:shuntdownNow\(\) > shutdown\(\) > awaitTermination\(\)
- 簡介
- 概述
- 進程vs線程
- 資源限制
- 有關并行的兩個定律
- 線程同步和阻塞
- 線程阻塞
- 線程的特性
- 守護線程
- 線程異常
- Thread
- 線程狀態
- 線程中斷
- wait¬ify
- suspend&resume
- join&yield
- notify¬ifyAll
- Thread.sleep
- 線程任務
- Runnable
- Callable
- Future模式
- FutureTask
- 線程實現方式
- 內核線程實現
- 用戶線程實現
- 混合實現
- Java線程的實現
- java與協程
- 纖程-Fiber
- 線程調度
- 多線程協作方式
- 阻塞
- 放棄
- 休眠
- 連接線程
- 線程估算公式
- 線程活躍性
- 死鎖
- 線程安全性
- 對象的發布與逸出
- 構造方法溢出
- 線程封閉
- 對象的可變性
- 原子性
- 原子操作
- CPU原子操作原理
- 總線鎖
- 緩存鎖
- JAVA如何實現原子操作
- long和double讀寫操作原子性
- Adder和Accumulator
- 線程性能
- 同步工具類
- 閉鎖
- CountDownLatch
- FutureTask
- 信號量
- 柵欄
- CyclicBarrier
- Exchanger
- 并發編程
- volatile
- synchronized
- 無鎖
- 偏向鎖
- 輕量級鎖
- 鎖的優缺點對比
- 鎖升級
- 鎖消除
- Monitor
- synchronized語法
- Mutex Lock
- synchronized實踐問題
- synchronized&ReentrantLock
- Lock
- ReentrantLock
- Condition
- 讀寫鎖
- ReadWriteLock
- StampedLock
- 線程池
- Executor
- ExecutorService
- Executors
- ThreadPoolExecutor
- RejectedExecutionHandler
- ThreadFactory
- 線程池大小公式
- 動態調整線程池大小
- Fork/Join框架
- ForkJoinPool
- CompletableFuture
- JUC并發工具包
- LockSupport
- 延時任務與周期任務
- Timer
- TimerTask
- 異構任務并行化
- CompletionService
- volatile和synchronized比較
- 鎖優化
- 鎖相關概念
- 悲觀鎖(排它鎖)
- 樂觀鎖
- 自旋鎖
- 樂觀鎖vs悲觀鎖
- JVM鎖優化-鎖消除
- ThreadLocal
- InheritableThreadLocal
- TransmittableThreadLocal
- ThreadLocalRandom
- 無鎖
- AtomicInteger
- Unsafe
- AtomicReference
- AtomicStampedReference
- AtomicIntegerArray
- AtomicIntegerFieldUpdater
- 無鎖Vector
- LongAdder
- LongAccumulator
- 常見鎖類型
- 悲觀鎖&獨占鎖
- 樂觀鎖
- 樂觀鎖vs悲觀鎖
- 自旋鎖vs適應性自旋鎖
- 公平鎖vs非公平鎖
- 可重入鎖vs非可重入鎖
- 獨享鎖vs共享鎖
- 互斥鎖
- CAS
- AQS介紹
- AQS深入剖析
- AQS框架
- AQS核心思想
- AQS數據結構
- 同步狀態State
- ReentrantLock vs AQS
- AQS與ReentrantLock的關聯
- ReentrantLock具體實現
- 線程加入等待隊列
- 等待隊列中線程出隊列時機
- 如何解鎖
- 中斷恢復后的執行流程
- ReentrantLock的可重入應用
- JUC中的應用場景
- 自定義同步工具
- CLH鎖
- 并發框架
- Akka
- Disruptor-無鎖緩存框架
- 常見面試題
- 兩個線程交替打印A和B
- 附錄