Android多線程:必須了解的多線程基礎(chǔ)知識(shí)匯總


前言

  • 多線程的應(yīng)用在開(kāi)發(fā)中非常常見(jiàn)
  • 今天,我將獻(xiàn)上一份全面 & 詳細(xì)的多線程基礎(chǔ)知識(shí)匯總,希望你們喜歡。

Carson帶你學(xué)多線程系列
基礎(chǔ)匯總
Android多線程:基礎(chǔ)知識(shí)匯總
基礎(chǔ)使用
Android多線程:繼承Thread類使用(含實(shí)例教程)
Android多線程:實(shí)現(xiàn)Runnable接口使用(含實(shí)例教程)
復(fù)合使用
Android 多線程:AsyncTask使用教程(含實(shí)例講解)
Android 多線程:AsyncTask原理及源碼分析
Android多線程:HandlerThread使用教程(含實(shí)例講解)
Android多線程:HandlerThread原理及源碼分析
Android多線程:IntentService使用教程(含實(shí)例講解)
Android多線程:IntentService的原理及源碼分析
Android多線程:線程池ThreadPool全方位教學(xué)
相關(guān)使用
Android異步通信:這是一份全面&詳細(xì)的Handler機(jī)制學(xué)習(xí)攻略
Android多線程:手把手教你全面學(xué)習(xí)神秘的Synchronized關(guān)鍵字
Android多線程:帶你了解神秘的線程變量 ThreadLocal


目錄

示意圖

1. 線程 - 介紹

1.1 定義

一個(gè)基本的CPU執(zhí)行單元 & 程序執(zhí)行流的最小單元。

1.2 特點(diǎn)

  • 比進(jìn)程更小的可獨(dú)立運(yùn)行的基本單位,可理解為:輕量級(jí)進(jìn)程;
  • 組成:線程ID + 程序計(jì)數(shù)器 + 寄存器集合 + 堆棧;
  • 線程自己不擁有系統(tǒng)資源,與其他線程共享進(jìn)程所擁有的全部資源。

1.3 作用

減少程序在并發(fā)執(zhí)行時(shí)所付出的時(shí)空開(kāi)銷,提高操作系統(tǒng)的并發(fā)性能。

1.4 狀態(tài)說(shuō)明

擁有類似于進(jìn)程的就緒、阻塞、運(yùn)行3種基本狀態(tài),具體如下圖:

示意圖

2. 線程分類

線程主要分為:守護(hù)線程、非守護(hù)線程(用戶線程)

2.1 守護(hù)線程

守護(hù)用戶線程的線程,即在程序運(yùn)行時(shí)為其他線程提供一種通用服務(wù),如垃圾回收線程。設(shè)置該線程為守護(hù)線程的方式如下:

thread.setDaemon(true);

2.2 非守護(hù)線程(用戶線程)

主要包括:主線程 & 子線程。

a. 主線程(UI線程)

  • 定義:Android系統(tǒng)在程序啟動(dòng)時(shí)會(huì)自動(dòng)啟動(dòng)一條主線程
  • 作用:處理四大組件與用戶進(jìn)行交互的事情(如UI、界面交互相關(guān))
  • 注:因?yàn)橛脩綦S時(shí)會(huì)與界面發(fā)生交互,因此主線程任何時(shí)候都必須保持很高的響應(yīng)速度,所以主線程不允許進(jìn)行耗時(shí)操作,否則會(huì)出現(xiàn)ANR

b. 子線程(工作線程)

手動(dòng)創(chuàng)建的線程,主要用于耗時(shí)的操作(網(wǎng)絡(luò)請(qǐng)求、I/O操作等)

2.3 守護(hù)線程 與 非守護(hù)線程的區(qū)別

區(qū)別:虛擬機(jī)是否已退出:

  • 當(dāng)所有用戶線程結(jié)束時(shí),因?yàn)闆](méi)有守護(hù)的必要,所以守護(hù)線程也會(huì)終止,虛擬機(jī)也同樣退出;
  • 反過(guò)來(lái),只要任何用戶線程還在運(yùn)行,守護(hù)線程就不會(huì)終止,虛擬機(jī)就不會(huì)退出

3. 線程優(yōu)先級(jí)

3.1 表示

線程優(yōu)先級(jí)分為10個(gè)級(jí)別,分別用Thread類常量表示。

public static final int MIN_PRIORITY = 1; // 優(yōu)先級(jí)1
public static final int NORM_PRIORITY = 5; // 優(yōu)先級(jí)5
public static final int MAX_PRIORITY = 10; // 優(yōu)先級(jí)10

3.2 設(shè)置

  • 通過(guò)方法setPriority(int grade)進(jìn)行優(yōu)先級(jí)設(shè)置
  • 默認(rèn)線程優(yōu)先級(jí)是5,即 Thread.NORM_PRIORITY

4. 多線程 - 介紹

4.1 定義

多個(gè)線程同時(shí)進(jìn)行,即多個(gè)任務(wù)同時(shí)進(jìn)行

  1. 其實(shí),計(jì)算機(jī)任何特定時(shí)刻只能執(zhí)行一個(gè)任務(wù);
  2. 多線程只是一種錯(cuò)覺(jué):只是因?yàn)镴VM快速調(diào)度資源來(lái)輪換線程,使得線程不斷輪流執(zhí)行,所以看起來(lái)好像在同時(shí)執(zhí)行多個(gè)任務(wù)而已

4.2 作用

Android官方聲明:在多線程編程時(shí)有兩大原則:

  1. 不要阻塞UI線程(即主線程):?jiǎn)尉€程會(huì)導(dǎo)致主線程阻塞,然后出現(xiàn)ANR錯(cuò)誤:主線程被阻塞超過(guò)5s則會(huì)出現(xiàn)錯(cuò)誤
  2. 不要在UI線程之外更新UI組件

所以,我們需要多線程(1個(gè)主線程+x個(gè)工作線程)來(lái)解決上述兩個(gè)問(wèn)題:

  • 將耗時(shí)任務(wù)放在工作線程中進(jìn)行

對(duì)應(yīng)原則:不要阻塞UI線程(即主線程),即當(dāng)我們有耗時(shí)的任務(wù),如果在UI線程中執(zhí)行,那就會(huì)阻塞UI線程了,必須要拋到工作線程中去執(zhí)行;

  • 將更新UI組件放在主線程中進(jìn)行

對(duì)應(yīng)原則:不要在UI線程之外訪問(wèn)UI組件,即更新UI組件時(shí),一定得在UI線程里執(zhí)行,故需要在工作線程中執(zhí)行的任務(wù)結(jié)果返回到UI線程中去更新組件

4.3 應(yīng)用場(chǎng)景

  • 將耗時(shí)任務(wù)從主線程拋到工作線程中進(jìn)行
  • 將更新UI組件任務(wù)從工作線程拋到主線程中進(jìn)行

4.4 實(shí)現(xiàn)方式

Android多線程實(shí)現(xiàn)方式包括:


示意圖

5. 線程調(diào)度

5.1 調(diào)度方式

  • 當(dāng)系統(tǒng)存在大量線程時(shí),系統(tǒng)會(huì)通過(guò)時(shí)間片輪轉(zhuǎn)的方式調(diào)度線程,因此線程不可能做到絕對(duì)的并發(fā)
  • 處于就緒狀態(tài)(Runnable)的線程都會(huì)進(jìn)入到線程隊(duì)列中等待CPU資源

同一時(shí)刻在線程隊(duì)列中可能有很多個(gè)

  • 在采用時(shí)間片的系統(tǒng)中,每個(gè)線程都有機(jī)會(huì)獲得CPU的資源以便進(jìn)行自身的線程操作;當(dāng)線程使用CPU資源的時(shí)間到后,即時(shí)線程沒(méi)有完成自己的全部操作,JVM也會(huì)中斷當(dāng)前線程的執(zhí)行,把CPU資源的使用權(quán)切換給下一個(gè)隊(duì)列中等待的線程。

被中斷的線程將等待CPU資源的下一次輪回,然后從中斷處繼續(xù)執(zhí)行

5.2 調(diào)度優(yōu)先級(jí)

Java虛擬機(jī)(JVM)中的線程調(diào)度器負(fù)責(zé)管理線程,并根據(jù)以下規(guī)則進(jìn)行調(diào)度:

  1. 根據(jù)線程優(yōu)先級(jí)(高-低),將CPU資源分配給各線程
  2. 具備相同優(yōu)先級(jí)的線程以輪流的方式獲取CPU資源

這里需要特別注意的是:優(yōu)先級(jí)高的,只是獲得資源的機(jī)會(huì)高一些,并非完全獨(dú)占CPU運(yùn)行;優(yōu)先級(jí)低的也并非要等高優(yōu)先級(jí)的線程運(yùn)行完才能輪到,是相對(duì)來(lái)說(shuō)獲得資源的機(jī)率低一些,僅此而已。


6. 線程同步

  • 定義:當(dāng)線程A使用同步方法A時(shí),其他線程必須等到線程A使用完同步方法A后才能使用
  • 同步方法用關(guān)鍵字 Synchronized 進(jìn)行修飾
public synchronized void Sb_Android(){
        }

7. 線程聯(lián)合

  • 定義:線程A在占有CPU資源期間,通過(guò)調(diào)用join()方法中斷自身線程執(zhí)行,然后運(yùn)行聯(lián)合它的線程B,直到線程B執(zhí)行完畢后線程A再重新排隊(duì)等待CPU資源,這個(gè)過(guò)程稱為線程A聯(lián)合線程B
  • 線程A聯(lián)合線程B,即在線程A的執(zhí)行操作里定義:
B.join();

8. 進(jìn)程 - 介紹

8.1 定義

是進(jìn)程實(shí)體的運(yùn)行過(guò)程 & 系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位

8.2 作用

使多個(gè)程序可 并發(fā)執(zhí)行,以提高系統(tǒng)的資源利用率和吞吐量

8.3 進(jìn)程狀態(tài)說(shuō)明(前三個(gè)為基礎(chǔ)狀態(tài))

示意圖

注意 就緒、阻塞狀態(tài)的區(qū)別:

  1. 就緒狀態(tài):進(jìn)程缺少的資源 = 處理機(jī),只要獲得處理機(jī)資源立即執(zhí)行
  2. 等待狀態(tài):指 進(jìn)程缺少其他資源(除了處理機(jī)) / 等待某一事件

8.4 狀態(tài)轉(zhuǎn)換

示意圖

9. 線程與進(jìn)程的區(qū)別

示意圖

10. 單/多進(jìn)程、單/多線程的區(qū)別

假設(shè):進(jìn)程 = 桌子,單線程 = 1個(gè)人吃飯

  • 單進(jìn)程、單線程:一個(gè)人在一個(gè)桌子上吃飯
  • 單進(jìn)程、多線程:多個(gè)人在同一個(gè)桌子上一起吃飯
  • 多進(jìn)程、單線程:多個(gè)人每個(gè)人在自己的桌子上吃飯

11. 總結(jié)

  • 本文主要全面介紹了多線程中的基礎(chǔ)知識(shí)
  • 下一篇文章我將對(duì)講解Android多線程的相關(guān)知識(shí),感興趣的同學(xué)可以繼續(xù)關(guān)注Carson_Ho的簡(jiǎn)書(shū)

Carson帶你學(xué)多線程系列
基礎(chǔ)匯總
Android多線程:基礎(chǔ)知識(shí)匯總
基礎(chǔ)使用
Android多線程:繼承Thread類使用(含實(shí)例教程)
Android多線程:實(shí)現(xiàn)Runnable接口使用(含實(shí)例教程)
復(fù)合使用
Android 多線程:AsyncTask使用教程(含實(shí)例講解)
Android 多線程:AsyncTask原理及源碼分析
Android多線程:HandlerThread使用教程(含實(shí)例講解)
Android多線程:HandlerThread原理及源碼分析
Android多線程:IntentService使用教程(含實(shí)例講解)
Android多線程:IntentService的原理及源碼分析
Android多線程:線程池ThreadPool全方位教學(xué)
相關(guān)使用
Android異步通信:這是一份全面&詳細(xì)的Handler機(jī)制學(xué)習(xí)攻略
Android多線程:手把手教你全面學(xué)習(xí)神秘的Synchronized關(guān)鍵字
Android多線程:帶你了解神秘的線程變量 ThreadLocal


歡迎關(guān)注Carson_Ho的簡(jiǎn)書(shū)

不定期分享關(guān)于安卓開(kāi)發(fā)的干貨,追求短、平、快,但卻不缺深度。


請(qǐng)點(diǎn)贊!因?yàn)槟愕墓膭?lì)是我寫(xiě)作的最大動(dòng)力!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容