多線程的總結

1>什麼是線程與進程
什麼是進程
進程是指在系統中正在運行的一個應用程序
每個進程之間是獨立的,每個進程均運行在其專用且受保護的內存空間內
比如同時打開QQ xcode 系統就會分別啓動2個進程

什麼是線程
1個進程要想執行任務,必須得有線程(每1個進程至少要有1條線程)
線程是進程的基本執行單元,一個進程(程序)的所有任務都在線程中執行
比如使用酷狗播放音樂,使用迅雷下載電影,都需要在線程中執行

2> 線程的串行
如果要在1個線程中執行多個任務,那麼只能一個一個地按順序執行這些任務
也就是說,在同一時間內,1個線程只能執行1個任務
因此,也可以認爲線程是進程中的1條執行路徑

3>多線程
1個進程中可以開啓多條線程,每條線程可以並行(同時)執行不同的任務
多線程的原理
同一時間,CPU只能處理1條線程,只有1條線程在工作(執行)
多線程併發(同時)執行,其實是CPU快速地在多條線程之間調度(切換)
如果CPU調度線程的時間足夠快,就造成了多線程併發執行的假象

多線程的優缺點
優點
能適當提高程序的執行效率   能適當提高資源利用率(CPU,內存利用率)
缺點
開啓線程需要佔用一定的內存空間(默認情況下,主線程佔用1M,子線程佔用512KB),如果開啓大量的線程,會佔用大量的內存空間,降低程序的性能
線程越多,CPU在調度線程上的開銷就越大
程序設計更加複雜:比如線程之間的通信,多線程的數據共享

4>主線程    /****** 重要  *****/
主線程的主要作用
主線程:一個iOS程序運行後,默認會開啓1條線程,稱爲主線程“UI線程”.
顯示\刷新UI界面
處理UI事件(比如點擊事件,滾動事件,拖拽事件等)
主線程的使用注意
不要將比較耗時的操作放到主線程
耗時操作會卡住主線程,嚴重影響UI的流暢度,給用戶一種的壞體驗
不要同時開啓太多的線程(1-3條即可,不要超過5條)
主線程:UI線程,顯示,刷新UI界面,處理UI控件的事件
子線程:後臺線程,異步線程
耗時操作的執行
將耗時操作放在子線程(後臺線程,非主線程,異步線程



二:多線程的基本使用:
1.多線程的分類
iOS中多線程的實現方案
 NSThread GCD NSOperation
NSThread
一個NSThread對象就代表一條線程
//創建線程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
//需要執行的內容
…….
//啓動線程
[thread start];

2.其他創建子線程的方式
1> 創建子線程並自動啓動
[NSThread detachNewThreadSelector:@selector(download) toTarget:self withObject:nil];
2> 隱式創建子線程
[self performSelectorInBackground:@selector(download) withObject:nil];

[NSThread currentThread]獲取當前線程
[NSThread mainThread]獲取主線程

+ (BOOL)isMainThread;//判斷所在方法是否在主線程中
- (BOOL)isMainThread;//判斷某個線程是否爲主線程
3> 線程的名字
- (void)setName:(NSString *)n;
- (NSString *)name;

4> 控制線程的狀態

1.啓動線程
- (void)start;
2.阻塞(暫停)線程
+(void)sleepUntilDate:(NSDate *)date;
+(void)sleepForTimeInterval:(NSTimeInterval)ti; //阻塞當前的線程,一般不建議使用
 //一旦定製好 延遲任務後 不會卡住當前線程,建議使用
    [self performSelector:@selector(download) withObject:nil afterDelay:3.0f];
進入阻塞狀態
3.強制停止線程
+ (void)exit;
進入死亡狀態

例如:
- (void)threadCreate3
{
   
//隱式創建子線程
    [
self performSelectorInBackground:@selector(download:) withObject:@"隱式創建子線程調用的方法"];
}
- (void)threadCreate2
{
   
//創建一個子線程 並且自動啓動
    [
NSThread detachNewThreadSelector:@selector(download:) toTarget:self withObject:@"http://www.baidu.com/1.jpg"];
}
- (void)download:(NSString *)url
{
   
NSLog(@"%s thread=%@ url=%@",__func__,[NSThread currentThread],url);
}
- (void)threadCreate1
{
   
//1.創建一個子線程
   
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    thread.
name = @"打印";
   
//2.啓動線程
    [thread
start];
}


2。 多線程的安全隱患
1>.資源共享
塊資源可能會被多個線程共享,也就是多個線程可能會訪問一塊資源
.當多個線程訪問同一塊資源時,很容易引發數據錯亂和數據安全問題
2>安全隱患解決-互斥鎖(同步鎖)
1.互斥鎖使用模式
@synchronized(鎖對象) {
    //需要鎖定的代碼,即引起安全隱患的地方
}
//注意:鎖定1份代碼只用1把鎖,用多把鎖是無效的
缺點:需要消耗大量的CPU資源


例如:
//賣票的方法

    _thread3 = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket) object:nil];
    _thread3.name = @"3號窗口”; //此處若有多個窗口時會造成多個窗口請求同一張票而造成線程安全
- (void)sellTicket
{
    while (1) {
        //()裏的對象是鎖對象 可以是任意類型的對象 稱爲同步鎖 也叫 互斥鎖
       
@synchronized(self) {
           
if (_count<=0) {
               
NSLog(@"賣光");
               
return;
            }
else {
                [
NSThread sleepForTimeInterval:1];
               
_count -= 1;
               
NSLog(@"%@賣票 還剩%d",[NSThread currentThread].name,_count);
            }
        }//解鎖
    }
}


三:線程間的通信:/*****  重要   ****/

1.什麼叫做線程間通信
1個進程中,線程往往不是孤立存在的,多個線程之間需要經常進行通信,即: 1個線程傳遞數據給另1個線程, 1個線程中執行完特定任務後,轉到另1個線程繼續執行任務

線程間通信常用方法
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
例如:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章