概念
原文來自:https://blog.csdn.net/csdn_aiyang/article/details/65442540
了解什么是進(jìn)程全庸?什么是線程?
進(jìn)程:是系統(tǒng)的執(zhí)行單位半火,每一個Application都是一個進(jìn)程,APP啟動時系統(tǒng)默認(rèn)有一個主線程即為UI線程赠堵,但是UI線程不能做耗時操作医清,這里就要把耗時的操作交給子線程執(zhí)行。
線程:Thread?是操作系統(tǒng)能夠進(jìn)行運算調(diào)度的最小單位铺罢,它被包含在進(jìn)程之中艇挨,是進(jìn)程中的實際運作單位。
線程的幾種狀態(tài):
1韭赘、wait() -等待狀態(tài)?缩滨,并且釋放所有持有對象的lock鎖,直到notify()/notifyAll()被喚醒后放到鎖定池(lock blocked pool )泉瞻,釋放同步鎖使線程回到可運行狀態(tài)(Runnable)脉漏。
2、sleep()袖牙。使一個線程處于睡眠狀態(tài)侧巨,是一個靜態(tài)方法,調(diào)用此方法要捕捉Interrupted異常鞭达,醒來后進(jìn)入runnable狀態(tài)司忱,等待JVM調(diào)度。
3.notify();換新一個等待狀態(tài)的線程畴蹭,這個將要喚醒的線程是由JVM的分配的優(yōu)先級線程來調(diào)度并喚醒坦仍;
4.notifyAll()使所有等待狀態(tài)的線程喚醒,讓他們競爭
5.join()叨襟。使一個線程中斷繁扎,IO完成會回到Runnable狀態(tài),等待JVM的調(diào)度
6.Synchronized()糊闽;同步鎖梳玫。使Running狀態(tài)的線程加同步鎖使其進(jìn)入(lock blocked pool ),同步鎖被釋放進(jìn)入可運行狀態(tài)(Runnable)。
7.yield()右犹,線程禮讓 汽纠。當(dāng)線程在runnable狀態(tài)時是處于被調(diào)度的線程,此時的調(diào)度順序是不一定的傀履。Thread類中的yield方法可以讓一個running狀態(tài)的線程轉(zhuǎn)入runnable虱朵。
基礎(chǔ)性概念
1.并行 :?當(dāng)有多個線程在操作時,如果系統(tǒng)只有一個CPU,則它根本不可能真正同時進(jìn)行一個以上的線程莉炉,它只能把CPU運行時間劃分成若干個時間段,再將時間 段分配給各個線程執(zhí)行,在一個時間段的線程代碼運行時碴犬,其它線程處于掛起狀絮宁。.這種方式我們稱之為并發(fā)(Concurrent)。
2. 并行當(dāng)系統(tǒng)有一個以上CPU時,則線程的操作有可能非并發(fā)服协。當(dāng)一個CPU執(zhí)行一個線程時绍昂,另一個CPU可以執(zhí)行另一個線程,兩個線程互不搶占CPU資源偿荷,可以同時進(jìn)行窘游,這種方式我們稱之為并行(Parallel)。
? ? ?區(qū)別:并發(fā)和并行是即相似又有區(qū)別的兩個概念跳纳,并行是指兩個或者多個事件在同一時刻發(fā)生忍饰;而并發(fā)是指兩個或多個事件在同一時間間隔內(nèi)發(fā)生。在多道程序環(huán)境下寺庄,并發(fā)性是指在一段時間內(nèi)宏觀上有多個程序在同時運行艾蓝,但在單處理機系統(tǒng)中,每一時刻卻僅能有一道程序執(zhí)行斗塘,故微觀上這些程序只能是分時地交替執(zhí)行赢织。倘若在計算機系統(tǒng)中有多個處理機,則這些可以并發(fā)執(zhí)行的程序便可被分配到多個處理機上馍盟,實現(xiàn)并行執(zhí)行于置,即利用每個處理機來處理一個可并發(fā)執(zhí)行的程序,這樣贞岭,多個程序便可以同時執(zhí)行
3俱两、線程安全。指在并發(fā)的情況之下曹步,該代碼經(jīng)過多線程使用,線程的調(diào)度順序不影響任何結(jié)果休讳。線程不安全就意味著線程的調(diào)度順序會影響最終結(jié)果讲婚,比如某段代碼不加事務(wù)去并發(fā)訪問。
4俊柔、線程同步筹麸。指的是通過人為的控制和調(diào)度,保證共享資源的多線程訪問成為線程安全雏婶,來保證結(jié)果的準(zhǔn)確物赶。如某段代碼加入@synchronized關(guān)鍵字。線程安全的優(yōu)先級高于性能優(yōu)化留晚。
5.原子性酵紫。一個操作或者一系列操作,要么全部執(zhí)行要么全部不執(zhí)行。數(shù)據(jù)庫中的“事物”就是個典型的院子操作奖地。
6橄唬、可見性。當(dāng)一個線程修改了共享屬性的值参歹,其它線程能立刻看到共享屬性值的更改仰楚。比如JMM分為主存和工作內(nèi)存,共享屬性的修改過程是在主存中讀取并復(fù)制到工作內(nèi)存中犬庇,在工作內(nèi)存中修改完成之后僧界,再刷新主存中的值。若線程A在工作內(nèi)存中修改完成但還來得及刷新主存中的值臭挽,這時線程B訪問該屬性的值仍是舊值捂襟。這樣可見性就沒法保證。
7埋哟、有序性笆豁。程序運行時代碼邏輯的順序在實際執(zhí)行中不一定有序,為了提高性能赤赊,編譯器和處理器都會對代碼進(jìn)行重新排序闯狱。前提是,重新排序的結(jié)果要和單線程執(zhí)行程序順序一致抛计。
常見的多線程的實現(xiàn)方式
1哄孤、繼承Thread類,重寫run函數(shù)方法:
2吹截、實現(xiàn)Runnable接口瘦陈,重寫run函數(shù)方法
3、實現(xiàn)Callable接口波俄,重寫call函數(shù)方法:
Runnable 和Callable接口比較:
相同點:都可以被其他線程執(zhí)行任務(wù)
不同點:
a.重寫的方法不同?
?b Runnable重寫的方法不可以拋出異常晨逝, 并無返回值 ?
c.運行Callable任務(wù)可拿到一個Future對象,F(xiàn)uture表示異步計算的結(jié)果懦铺。通過Future對象可了解任務(wù)執(zhí)行情況,可取消任務(wù)的執(zhí)行捉貌。
4.Handler + Thread?
HandlerThread的好處是代碼看起來沒前面的版本那么亂,相對簡潔一點冬念。還有一個好處就是通過handlerThread.quit()或者quitSafely()使線程結(jié)束自己的生命周期趁窃。
5 ?AsyncTask
HandlerThread只開一條線程,任務(wù)都被阻塞在一個隊列中急前,那么就會使阻塞的任務(wù)延遲了
想多個耗時任務(wù)并發(fā)的執(zhí)行醒陆,那你更應(yīng)該選擇AsyncTask。
耗時任務(wù)執(zhí)行的四個方法:
onPreExecute()裆针;
doInBackground()刨摩;
onProgressUpdate() 寺晌;
onPostExecute()
6.IntentService
最后是IntentService,相信很多人也不陌生码邻,它是Service的子類折剃,用法跟Service也差不多,就是實現(xiàn)的方法名字不一樣像屋,耗時邏輯應(yīng)放在onHandleIntent(Intent intent)的方法體里怕犁,它同樣有著退出啟動它的Activity后不會被系統(tǒng)殺死的特點,而且當(dāng)任務(wù)執(zhí)行完后會自動停止己莺,無須手動去終止它奏甫。例如在APP里我們要實現(xiàn)一個下載功能,當(dāng)退出頁面后下載不會被中斷凌受,那么這時候IntentService就是一個不錯的選擇了阵子。