作者:機智的張尼瑪
楔子蘇格拉底曾說過:“學會了多線程,你就學會了壓榨CPU,就好像資本家對無產階級做的那事一樣 。”
多線程是開發人員必不可少的技術點,也是初學者不太容易掌握好的一個難點 。要想設計出優秀的程序,那必然需要合理的線程調度 。今天就給大家細說下Android中與多線程相關的知識點,揭開多線程神秘的面紗 。
本篇文章僅介紹多線程的各種實現方式,不過多涉及深入的基礎原理探究,達到“所見即所學 , 所學即可用”的效果 。關于各種多線程原理的深入探究 , 有機會放在后面逐一介紹 。
一、多線程是什么?我為什么要用多線程? 1.1 線程和進程的概念
按照操作系統中的描述,線程是CPU調度的最小單元,同時線程是一種有限的系統資源 。而進程一般指一個執行單元,在PC和移動設備上指一個程序或者一個應用 。一個進程可以包含多個線程 。
簡單點理解,一個Android APP就是一個進程,一個APP里面有多個線程,我們多線程編程的意義就是實現“一個APP多個線程” 。
有杠精可能會問,那我可不可以一個APP多個進程?又可不可以一個進程只有一個線程?
我告訴你 , 可以 , 都可以 。
單線程的APP只包括Android的UI線程也是能運行的;一個APP多個進程也是可以達到的 , 實現方式涉及到Android的IPC機制 , 這里不細說 。
1.2 為什么要使用多線程?
這里杠精可能會說,那你單線程也能跑,我為啥還要整多線程?
我告訴你,首先這句話從Android開發的角度來講,近似于一個假命題 。因為谷歌爸爸現在強制規定了不能在UI線程進行耗時操作,必須放到子線程里面去,除非你的程序不涉及耗時操作 。究其原因,是因為在UI線程進行耗時操作的話,給用戶的使用體驗就是界面“卡頓” 。同時,如果UI線程被阻塞超過一定時間會觸發ANR(Application Not Responding)錯誤 。
從底層的角度來講,多線程可以使得整個環境能夠異步執行,這有助于防止浪費CPU時鐘周期從而提高效率 。換言之,多線程能更充分的利用CPU資源,從而提高程序的運行效率 。
二、那我怎么進行多線程編程?2.1 Thread類和Runnable接口要想定義一個線程只需要新建一個類繼承自Thread,然后重寫父類的run方法即可
class MyThread extends Thread {@Overridepublic void run() {doSomething();}}//在需要的時候啟動線程new MyThread().start();優化一下?
我們可以沒必要繼承整個Thread類,只實現Runnable接口就好了
class MyThread implements Runnable {@Overridepublic void run() {doSomething()}}//啟動線程MyThread myThread = new MyThread();new Thread(myThread).start();那我不想專門再寫一個線程類怎么辦?可以使用匿名類
new Thread(new Runnable() {@Overridepublic void run() {doSomething();}}).start();2.2 線程池
2.2.1 線程池的意義既然我都會用Runnable接口來創建線程了,還要線程池干啥?其實不然,隨意創建線程的操作在實際開發中是極為不推薦的 。為啥?因為線程也是一種資源,反復的創建和銷毀線程會帶來一定性能上的額外開銷 。與其相比,線程池主要有以下幾個優點:
重用線程池中的線程,避免因為線程的創建和銷毀所帶來的性能開銷能有效控制線程池的最大并發數,避免大量的線程之間因相互搶占系統資源而導致的阻塞現象能夠對線程進行簡單的管理,并提供定時執行以及指定間隔循環執行等功能2.2.2 線程池的結構和原理一個完整的線程池應該有這么幾個組成部分
核心線程任務隊列非核心線程當我們通過線程池執行異步任務的時候,其實是依次進行了下面的流程
- “海馬體”長度不到10厘米 竟能偷走人類的記憶力
- 科學家揭秘:人類基因是肢體再生的關鍵
- 娜迦毒蛇,不是蛇而是世界上最辣的辣椒
- 世界最強十大航母:美航母還能領先多少年?
- 地球上的生物為何要依賴氧氣生存?氧氣是怎么產生的
- 大腦的奧秘,科學揭秘人類大腦如何一心二用!
- 破解挑戰者號背后的五大驚天謎團?
- 形容自己再做也得不到重視的成語
- 形容一次又一次的發生的成語
- 形容聲音吵很煩躁的成語
