iOS學習——鎖

來源:互聯網
上載者:User

標籤:等於   被鎖   產生   control   get   com   寫檔案   color   過程   

  在多線程學習中,必然會涉及到不同線程對同一資源的調取,面對這種調用不加以控制,就會產生資料混亂的情況。最常見的情況莫過於買票,多個售票員售票肯定是同時操作,這樣就會開啟多條線程,但是這種售票方式會產生票數不對的情況。

- (void)demo1 {    //售票員A    NSThread *threadA = [[NSThread alloc] initWithTarget:self selector:@selector(sellTikets) object:nil];    threadA.name = @"threadA";    [threadA start];        //售票員B    NSThread *threadB = [[NSThread alloc] initWithTarget:self selector:@selector(sellTikets) object:nil];    threadB.name = @"threadB";    [threadB start];    }- (void)sellTikets{        while (YES) {            if (self.tiketNum > 0) {                self.tiketNum -- ;                NSLog(@"還剩%d張票 %@",self.tiketNum,[NSThread currentThread]);            }else {                NSLog(@"票賣完了 %@",[NSThread currentThread]);          break;            }              } }

這裡對於第九張票出售了兩次,這就是用多線程產生的資料不安全問題,因為在多線程的資源共用中,就得上一把鎖來保證不會出現這種問題
- (void)sellTikets{        while (YES) {            @synchronized(self) {                if (self.tiketNum > 0) {                    self.tiketNum -- ;                    NSLog(@"還剩%d張票 %@",self.tiketNum,[NSThread currentThread]);                }else {                    NSLog(@"票賣完了 %@",[NSThread currentThread]);                    break;                }            }              }}
  @syn中需要傳一個全域變數參數,不一定是self,但是一定不能傳一個局部變數,因為這裡的參數作為一個鎖,要保證線上程執行的整個過程中都能鎖住線程,如果是一個局部變數,線程運行一次就被釋放掉了,根本毫無意義。
  互斥鎖保證了線程在運行中,每次只有一個線程能訪問到被鎖住的代碼塊,其他需要訪問的線程則在鎖外面睡眠等待,當一個線程執行完畢,才有下一個線程的執行。那麼,我們就得提到OC中的另外一個概念,原子性 atomic。在變數的聲明時,我們大多是情況下都是用nonatomic,用以提高運行效率,那麼atomic的作用在哪裡呢?一般我們在寫檔案的時候,會使用這樣的代碼:
    NSData*data = [@"iosSynChronized" dataUsingEncoding:NSUTF8StringEncoding];    [data  writeToFile:@"ios.text" atomically:YES];
  為了保證檔案寫入時候的安全,我們一般會選擇使用原子性。這樣,當文字在寫入的時候並不是直接建立一個本地檔案寫資料,而是建立一個虛擬檔案,當資料寫入完成,然後一次性形成要儲存的本地檔案,就不會出現,寫入的時候你刪除檔案,修改檔案造成的資料衝突。類似於一個鎖一樣,鎖住你要操作的東西,只有完成才能結束。同樣,給變數聲明atomic也就等於給變數賦值建立了一把鎖,只有一個線程完成對該變數的操作,下一個線程才能進行:
@property (atomic, strong) NSObject *lock;@end@implementation ViewController@synthesize lock = _lock;//重新getter和setter方法後,xcode就不會自動幫寫成員變數-(void)setLock:(NSObject *)lock {    @synchronized (self) {        _lock = lock;    }}- (NSObject *)lock {    return _lock;

  鎖能夠保證資料安全,但同樣也因此帶來了極大的不便,那就是效率問題,它將所有訪問操作都變成了單一操作,會浪費大量時間,這也是蘋果的UIKIT同樣採用線程不安全方式的原因,考慮到了效率問題。

 

 

iOS學習——鎖

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.