標籤:
/*
不是技術性的文章,只是記錄自己每天學習的方式
----------------------------程式猿的征途是星辰的大海
*/
[1] 何為多線程?
在多線程學習之前,很多人將進程,線程,非同步,同步,串列,並發混為一談,概念混淆很嚴重,甚至在使用一些第三方類庫的時候,不知道它進行資料請求使用的是何種方式,是非同步還是同步,多線程還是單線程。這裡我總結了幾天來接觸的多線程方面的知識,把概念性的內容理清。
進程:在IOS系統中,經常將一個應用等任務作為一個進程。
1個進程要想執行任務,必須得有線程(每1個進程至少要有1條線程)
線程:進程的組成單位,是進程中一些多次重複使用的代碼塊
線程是進程的基本執行單元,一個進程(程式)的所有任務都線上程中執行
比如使用酷狗播放音樂、使用迅雷下載電影,都需要線上程中執行
特點:一個線程同一時刻只能執行同一任務,如果多個任務交給同一任務來完成,
那麼該線程就會執行完一個任務後再去執行下個任務,直到任務全部被完成。
【多線程解釋】:
基於進程與線程的特性,我們在一個進程中可以開闢多條線程,他們可以並行(也就是時間上同步)的執行不同的任務,好比進程為項目組,線程為項目群組成員。多個線程可以同時執行不同的任務,就好比項目群組成員可以同時有不同的分工,如美工和程式猿有不同的專案工作。
我們需要注意的是:在單核的時代:CPU並不能同時執行多個線程!WTF!
雖然聽起來不能接受,但確實是這樣的,CPU在同一時間只能執行一個線程,之所以看起來多個線程能同時進行工作,這是因為CPU在多個線程之間來回切換的原因,如果cpu來回切換的速度夠快,就造成了多線程並發執行的假象。
多核心的時代裡, 核心級結構使用搶佔式的方式,將下一個線程安排在閒置核心上,這裡就不過多贅述,不論是單核還是多核心的方式,多線程都會提高對CPU工作的要求。
也因為這樣的原因,線程過多的情況下,CPU資源就會被過多的佔用,處理資料和資源的速度也會下降,所以要盡量控制一個進程中多線程的個數。(預設佔用記憶體情況為主線程佔用1M,子線程佔用512KB)
多線程的優點:能適當提高程式的執行效率,能適當提高資源的利用率
多線程的缺點:線程的開始和退出都是需要記憶體空間來支援的,程式的複雜度也被增加,
不利於閱讀理解,線程越多的時候,整個進程對CPU的開銷越大。
使用多線程需要多關注這方面的內容,不能過於隨意的開啟新線程。
[2]主線程 和次線程 (背景工作執行緒)
主線程:在每個進程中都存在一個主線程,所有的UI控制項搭建和手勢拖拽以及視圖滾動等都是在主線程中實現的。
我們常常需要進行一些耗時較長的工作,如資料請求,迴圈擷取資料或者處理內容,這些時候,主線程會被捆綁導致整個視圖螢幕無法被點擊,出現假死的情況,這對使用者體驗是致命的,我們為了避免出現這類的情況,往往採取開闢次線程的方法
次線程:又稱為背景工作執行緒,主要作用就在於分擔主線程的任務,並可以防止螢幕假死事故。
[3]串列和並行:
串列:使用 一個線程處理多個任務時,必須按照順序一個個執行。
並發:多個線程同步執行不同的任務。
[4]NSThread 簡單的開啟多線程
對於NSThread來說,它是一種簡單的開啟多線程模式的方法。通過在主線程執行個體化它的對象,執行start方法(類方法初始化的NSThread對象自動執行),就可以簡單的實現一個次線程。
<1>簡單實現多線程的例子
//在視圖中建立兩個按鈕-(void)creatUIButton{ NSArray * [email protected][@"線程1",@"線程2"]; for(int i=0;i<2;i++){ UIButton * btn=[UIButton buttonWithType:UIButtonTypeCustom]; btn.frame=CGRectMake(110, 100+100*i, 100, 30); btn.tag=i+1; btn.backgroundColor=[UIColor grayColor]; [btn setTitle:arr[i] forState:UIControlStateNormal]; [btn setTitleColor:[UIColor cyanColor ] forState:UIControlStateNormal]; [btn addTarget:self action:@selector(pressBtn:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn]; }}//執行按鈕的點擊事件-(void)pressBtn:(id)sender{ //搭建子線程 UIButton * btn = (UIButton *)sender; //多個線程並發工作 互不影響 if(btn.tag==1){ //1??類方法建立線程對象 /* 參數解釋:第一個參數為選取器方法 第二個參數為方法響應者 第三個對象為傳遞的參數,為OC對象 */ NSNumber * [email protected]10; [NSThread detachNewThreadSelector:@selector(threadMain1:) toTarget:self withObject:num]; //使用類方法建立線程對象,不需要手動開啟線程,只要線程被建立,就會自動調用線程方法。 }else{ NSNumber * [email protected]10; //2??使用執行個體方法,建立線程對象,但必須手動開啟線程 NSThread * thread= [[NSThread alloc]initWithTarget:self selector:@selector(threadMain2:) object:num]; //手動開啟線程 [thread start]; }}//線程1執行代碼-(void)threadMain1:(NSNumber *)num{ NSLog(@"線程1 開始>>>>>>>>"); for (int i=0; i<[num intValue]; i++) { NSLog(@"線程1 >>>> i = %d",i); [NSThread sleepForTimeInterval:0.1 ]; //線程沉睡0.5秒 } NSLog(@"線程1 結束");//線程結束 就會立即退出 (消失)}//線程2執行代碼-(void)threadMain2:(NSNumber *)num{ NSLog(@"線程2 開始!-------------!"); for (int i=0; i<[num intValue]; i++) { NSLog(@"線程2 i = %d",i*1000); [NSThread sleepForTimeInterval:0.3]; //線程沉睡0.5秒 } NSLog(@"線程2 結束"); }
-------在該執行個體中我們先點擊線程一按鈕,隨後立即點擊線程2按鈕
如果是在主線程中執行的兩個點擊事件,它們會怎麼執行了?
這個想必很多人都清楚,在點擊第一個按鈕之後,隨後點擊第二個按鈕,他們的點擊事件是依次進行的。
在按鈕1的點擊事件還沒有結束的時候,按鈕2的點擊事件不會響應。
那麼如果是在次線程中執行的兩個點擊事件,它們會怎麼執行了?
我們來看該執行個體的執行結果
可以看出線上程一的點擊事件還沒有結束的時候,點擊線程2按鈕,程式立刻開啟了線程2方法。因此,我們可以知道:
多線程不會受彼此幹擾,只要從主線程開闢一個次線程,它就能獨立的完成你安排的任務。我們也可以在主線程中列印一些標誌性的內容,可以看出,主線程的任務不會因為次線程在進行而終止,它會繼續執行自己的代碼而不是等待次線程結束。
IOS多線程管理<1>關於多線程你必須知道的二三事