iOS開發多線程篇-GCD介紹

來源:互聯網
上載者:User

標籤:

原文  http://www.cnblogs.com/wendingding/p/3805841.html

iOS開發多線程篇—安全執行緒

一、多線程的安全隱患

資源共用

1 塊資源可能會被多個線程共用,也就是多個線程可能會訪問同一塊資源

比如多個線程訪問同一個對象、同一個變數、同一個檔案

當多個線程訪問同一塊資源時,很容易引發資料錯亂和資料安全問題

樣本一:

樣本二:

問題代碼:

 1 // 2 //  YYViewController.m 3 //  05-安全執行緒 4 // 5 //  Created by apple on 14-6-23. 6 //  Copyright (c) 2014年 itcase. All rights reserved. 7 // 8  9 10 #import "YYViewController.h"11 12 @interface YYViewController ()13 //剩餘票數14 15 @property(nonatomic,assign) int leftTicketsCount;16 @property(nonatomic,strong)NSThread *thread1;17 @property(nonatomic,strong)NSThread *thread2;18 @property(nonatomic,strong)NSThread *thread3;19 20 21 @end22 23 24 @implementation YYViewController25 26 27 - (void)viewDidLoad28 {29     [super viewDidLoad];30 31     //預設有20張票32 33     self.leftTicketsCount=10;34 35     //開啟多個線程,類比售票員售票36 37     self.thread1=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];38 39     [email protected]"售票員A";40 41     self.thread2=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];42 43     [email protected]"售票員B";44 45     self.thread3=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];46     [email protected]"售票員C";47 }48 49  50 -(void)sellTickets51 {52     while (1) {53         //1.先檢查票數54         int count=self.leftTicketsCount;55         if (count>0) {56             //暫停一段時間57             [NSThread sleepForTimeInterval:0.002];58 59             //2.票數-160            self.leftTicketsCount= count-1;61  62             //擷取當前線程63             NSThread *current=[NSThread currentThread];64             NSLog(@"%@--賣了一張票,還剩餘%d張票",current,self.leftTicketsCount);65         }else66         {67             //退出線程68             [NSThread exit];69         }70     }71 }72 73 74 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event75 { 76     //開啟線程77 78    [self.thread1 start];79     [self.thread2 start];80     [self.thread3 start];81 82 }83 84 @end

列印結果:

二、安全隱患分析

 

三、如何解決

互斥鎖使用格式

@synchronized( 鎖對象 ) { //  需要鎖定的代碼   }

注意: 鎖定 1 份代碼只用 1 把鎖,用多把鎖是無效的

程式碼範例:

 1 // 2 //  YYViewController.m 3 //  05-安全執行緒 4 // 5 //  Created by apple on 14-6-23. 6 //  Copyright (c) 2014年 itcase. All rights reserved. 7 // 8  9 #import "YYViewController.h"10 11 @interface YYViewController ()12 13 //剩餘票數14 @property(nonatomic,assign) int leftTicketsCount;15 @property(nonatomic,strong)NSThread *thread1;16 @property(nonatomic,strong)NSThread *thread2;17 @property(nonatomic,strong)NSThread *thread3;18 @end19 20 @implementation YYViewController21 22 - (void)viewDidLoad23 {24     [super viewDidLoad];25     //預設有20張票26     self.leftTicketsCount=10;27     //開啟多個線程,類比售票員售票28 29     self.thread1=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];30 31     [email protected]"售票員A";32 33     self.thread2=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];34 35     [email protected]"售票員B";36 37     self.thread3=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];38 39     [email protected]"售票員C";40 }41 42 43 -(void)sellTickets44 {45     while (1) {46         @synchronized(self){//只能加一把鎖47         //1.先檢查票數48 49         int count=self.leftTicketsCount;50         if (count>0) {51             //暫停一段時間52             [NSThread sleepForTimeInterval:0.002];53             //2.票數-154 55            self.leftTicketsCount= count-1;56             //擷取當前線程57             NSThread *current=[NSThread currentThread];58             NSLog(@"%@--賣了一張票,還剩餘%d張票",current,self.leftTicketsCount);59 60         }else61         {62             //退出線程63             [NSThread exit];64         }65         }66     }67 }68 69 70 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event71 {72 73     //開啟線程74    [self.thread1 start];75     [self.thread2 start];76     [self.thread3 start];77 }78 79 @end

執行

互斥鎖的優缺點

優點:能有效防止因多線程搶奪資源造成的資料安全問題

缺點:需要消耗大量的 CPU 資源

互斥鎖的使用前提:多條線程搶奪同一塊資源  

相關專業術語: 線程同步, 多條線程按順序地執行任務

互斥鎖,就是使用了線程同步技術

四:原子和非原子屬性

OC 在定義屬性時有 nonatomic 和 atomic 兩種選擇

atomic :原子屬性,為 setter 方法加鎖(預設就是 atomic )

nonatomic :非原子屬性,不會為 setter 方法加鎖

atomic 加鎖原理

1 @property (assign, atomic) int age;2 3 - (void)setAge:(int)age4 { 5 6     @synchronized(self) { 7        _age = age;8     }9 }

原子和非原子屬性的選擇

nonatomic 和 atomic 對比

atomic : 安全執行緒,需要消耗大量的資源

nonatomic : 非安全執行緒,適合記憶體小的行動裝置

iOS 開發的建議

所有屬性都聲明為 nonatomic

盡量避免多線程搶奪同一塊資源

盡量將加鎖、資源搶奪的商務邏輯交給伺服器端處理,減小移動用戶端的壓力

iOS開發多線程篇-GCD介紹

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.