[TOC]
## 開啟線程的三種方式
~~~
//第一種是Thread開啟
Thread t = new Thread(){
public void run(){
}
}.start();
//Runnable開啟
Runnbale r = new Runnbale(){
public void run(){
}
}
new Thread(r).start();
//Callable作為內部類,返回Future。這里簡單說一下,Runnable與Future的區別
//1、Runnable無返回值,而Future有
//2、Runnable無法拋異常,而Future可以
Callable c = new Callable(){
public String call() throws Exception{
return "s";
}
}
ExecutorService mExecuterService = Executor.newSingleThreadPool();
Future future = mExecuterService.submit(c)
Future future
~~~
## 生命周期

## 中斷interrupt
### interrupt()
線程的thread.interrupt()方法是中斷線程,將會設置該線程的中斷狀態位,即設置為true,中斷的結果線程是死亡、還是等待新的任務或是繼續運行至下一步,就取決于這個程序本身。
### isInterrupted()
測試當前線程是否已經中斷。線程的中斷狀態?由該方法清除。換句話說,如果連續兩次調用該方法,則第二次調用將返回 false。
### 寫法
~~~
public void run() {
try {
...
/*
* 不管循環里是否調用過線程阻塞的方法如sleep、join、wait,這里還是需要加上
* !Thread.currentThread().isInterrupted()條件,雖然拋出異常后退出了循環,顯
* 得用阻塞的情況下是多余的,但如果調用了阻塞方法但沒有阻塞時,這樣會更安全、更及時。
*/
while (!Thread.currentThread().isInterrupted()&& more work to do) {
do more work
}
} catch (InterruptedException e) {
//線程在wait或sleep期間被中斷了
Thread.currentThread().interrupt();//重新設置中斷標示
} finally {
//線程結束前做一些清理工作
}
}
~~~
其實,Java的中斷是一種協作機制。也就是說調用線程對象的interrupt方法并不一定就中斷了正在運行的線程,它只是要求線程自己在合適的時機中斷自己。每個線程都有一個boolean的中斷狀態(這個狀態不在Thread的屬性上),interrupt方法僅僅只是將該狀態置為true。
比如對正常運行的線程調用interrupt()并不能終止他,只是改變了interrupt標示符。
一般說來,如果一個方法聲明拋出InterruptedException,表示該方法是可中斷的,比如wait,sleep,join,也就是說可中斷方法會對interrupt調用做出響應(例如sleep響應interrupt的操作包括清除中斷狀態,拋出InterruptedException),異常都是由可中斷方法自己拋出來的,并不是直接由interrupt方法直接引起的。
**Object.wait, Thread.sleep方法,會不斷的輪詢監聽 interrupted 標志位,發現其設置為true后,會停止阻塞并拋出 InterruptedException異常。**
## join()?
join()方法會使當前線程等待調用join()方法的線程結束后才能繼續執行
join的作用就是將線程串行化,需要注意的是,join()一定要放在現場開啟(start())后。
## wait sleep join
### sleep()?
sleep()方法需要指定等待的時間,它可以讓當前正在執行的線程在指定的時間內暫停執行,進入阻塞狀態
### wait()?
wait()方法需要和notify()及notifyAll()兩個方法一起介紹,這三個方法用于協調多個線程對共享數據的存取,所以必須在synchronized語句塊內使用,也就是說,調用wait(),notify()和notifyAll()的任務在調用這些方法前必須擁有對象的鎖。
### wait和sleep的區別
1. wait只能在同步(synchronize)環境中被調用,而sleep不需要。
2. 進入wait狀態的線程能夠被notify和notifyAll線程喚醒,但是進入sleeping狀態的線程不能被notify方法喚醒。
3. wait通常有條件地執行,線程會一直處于wait狀態,直到某個條件變為真。但是sleep僅僅讓你的線程進入睡眠狀態。
4. wait方法在進入wait狀態的時候會釋放對象的鎖,但是sleep方法不會。
5. wait方法是針對一個被同步代碼塊加鎖的對象,而sleep是針對一個線程。更詳細的講解可以參考《Java核心技術卷1》,里面介紹了如何使用wait和notify方法。
- Java
- Object
- 內部類
- 異常
- 注解
- 反射
- 靜態代理與動態代理
- 泛型
- 繼承
- JVM
- ClassLoader
- String
- 數據結構
- Java集合類
- ArrayList
- LinkedList
- HashSet
- TreeSet
- HashMap
- TreeMap
- HashTable
- 并發集合類
- Collections
- CopyOnWriteArrayList
- ConcurrentHashMap
- Android集合類
- SparseArray
- ArrayMap
- 算法
- 排序
- 常用算法
- LeetCode
- 二叉樹遍歷
- 劍指
- 數據結構、算法和數據操作
- 高質量的代碼
- 解決問題的思路
- 優化時間和空間效率
- 面試中的各項能力
- 算法心得
- 并發
- Thread
- 鎖
- java內存模型
- CAS
- 原子類Atomic
- volatile
- synchronized
- Object.wait-notify
- Lock
- Lock之AQS
- Lock子類
- 鎖小結
- 堵塞隊列
- 生產者消費者模型
- 線程池