Day 21
1. 多線程
1.1 優缺點
優點
提升資源利用率
提高用戶體驗
缺點
降低了其他線程執行概率
用戶會感受到軟件的卡頓
增加了系統資源壓力
多線程情況下的共享資源問題,線程衝突,線程安全問題
1.2 創建自定義線程類的兩種方式
class Thread類
Java中的線程類
Runnable接口的實現類,同時提供了很多線程的操作使用方法
interface Runnable接口
規定了What will be run?
只有一個方法 run 方法
方式一:
自定義線程類,繼承Thread類,重寫run方法
直接調用start方法啓動
方式二
自定義線程類,實現Runnable接口
通過Thread類的start方法啓動
1.3 Thread類方法
Constructor
Thread();
Thread(Runnable target);
Thread(String name);
Thread(Runnable target, String name);
Method
void setName(String name);
String getName();
void setPriority(int Priority);
int getPriority();
void start();
public static void sleep(int ms);
public static Thread currentThread();
2. 線程安全問題和解決方案
2.1 線程安全問題–共享資源使用問題
2.2 同步代碼塊
synchronized ( ) {
}
2.3 同步方法
synchronized 作爲關鍵字修飾方法爲同步方法
1. 靜態成員方法
鎖對象爲類文件
2. 非靜態成員方法
鎖對象爲this,當前類對象
2.4 Lock鎖
Java提供了一個對於線程安全問題,加鎖操作相對於同步代碼塊
1. Constructor
Lock lock = new ReentrantLock()
2. Method
加鎖
lock()
開鎖
unlock()
2.5 三種加鎖方式的總結
1. 一鎖一線程,一鎖多線程問題
靜態是一鎖多線程,非靜態是一鎖一線程
2. 涉及到同步問題,要考慮好鎖對象的選擇問題
同步代碼塊,同步方法,Lock對象
3. 守護線程
守護線程,也稱後臺線程,如果當前線程GG,守護線程也GG
守護線程一般用於:
1. 自動下載
2. 操作日誌
3. 操作監控
setDeamon(boolean flag)
true 守護線程
false 默認,正常線程
4. 線程狀態
4.1 六種線程狀態
Java中的線程有六種狀態
狀態
導致狀態發生條件
NEW(新建)
線程剛剛被創建,沒有啓動
RUNNABLE(可運行)
線程已經可以在JVM中運行,是否運行不確定
BLOCKED(鎖阻塞)
線程等待其他線程釋放鎖對象
WAITING(無限等待)
通過wait方法進入一個無限等待狀態,需要另一個線程notify或者notifyAll喚醒
TIMED_WAITING(計時等待)
當前線程是等待狀態,會在一定時間進入RUNNABLE方法,如Thread.sleep()或者Object中的wait(int ms)
TERMINATED(被終止)
因爲run方法運行結束,正常退出,或者出現異常導致退出
4.2 TIMED_WAITING(計時等待)
Thread.sleep(int ms);
當前線程休眠指定時間
Object.wait(int ms);
當前線程進入計時等待狀態
1. 計時完畢,線程進入RUNNABLE
2. 等待時間內,通過其他線程被notify或notifyAll喚醒
Sleep方法
1. 調用之後休眠指定時間
2. 必須執行在run方法內
3. 不會打開當前進程持有的鎖
4.3 BLOCKED(鎖阻塞)
線程中有鎖存在,線程未持有鎖,進入鎖阻塞狀態,線程需要等待其他線程釋放鎖對象。當本線程持有鎖對象後,進入可執行狀態。
鎖阻塞狀態線程是否能夠搶到鎖對象,有很多因素
1. 優先級問題,非決定因素
2. CPU執行概率問題
後期高併發一定存在多線程操作鎖問題,秒殺,搶購...
隊列方式解決
Tips
1. 重寫的方法的聲明必須一致,和父類或者接口中的方法聲明(包括異常拋出也要一致)