NSThread(二)

線程的創(chuàng)建和開啟

一個NSThread對象就是一個線程

// 創(chuàng)建線程兼蜈,可以對線程對象進(jìn)行操作斜友,可以進(jìn)行詳細(xì)的設(shè)置
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"take"];
// 開啟線程洽故,當(dāng)線程執(zhí)行完畢袱耽,自動進(jìn)入死亡狀態(tài)
[thread start];
    
// 創(chuàng)建并開啟線程庄新,不能對線程進(jìn)行詳細(xì)的設(shè)置
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"me"];

// 在后臺運行广恢,即隱式創(chuàng)建并開啟線程,不能對線程進(jìn)行詳細(xì)的設(shè)置
[self performSelectorInBackground:@selector(run:) withObject:@"hand"];

// 線程已啟動馋没,就會執(zhí)行self中的run方法昔逗,Object后面的參數(shù)是傳給run方法的參數(shù)值
-(void)run:(NSString*)string {
    for (int i=0; i<10000; i++) {
        NSLog(@" -- run -- %@ -- %zd -- %@",string,i,[NSThread currentThread]);
    }
}

// 線程的相關(guān)用法
// 獲得當(dāng)前線程
@property (class, readonly, strong) NSThread *currentThread;
// 線程的名字
@property (nullable, copy) NSString *name;
// 判斷是否是主線程
@property (readonly) BOOL isMainThread;
// 獲取主線程
@property (class, readonly, strong) NSThread *mainThread;
// 控制線程狀態(tài)
// 啟動線程,當(dāng)線程結(jié)束后篷朵,自動進(jìn)入死亡狀態(tài)
- (void)start;
// 取消線程
- (void)cancel;
// 阻塞(暫停)線程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
// 強制停止線程勾怒,進(jìn)入死亡狀態(tài)
+ (void)exit;
// 讓線程睡眠2秒(阻塞2秒)
[NSThread sleepForTimeInterval:2]; 
// 讓線程睡到遙遠(yuǎn)的未來,即永遠(yuǎn)的阻塞線程
[NSThread sleepUntilDate:[NSDate distantFuture]];
// 讓線程睡2秒
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
多線程的安全隱患

資源共享:一個資源被多個線程共享声旺,當(dāng)多個線程訪問一個資源時笔链,可能會引發(fā)數(shù)據(jù)錯亂和數(shù)據(jù)安全

image
image
互斥鎖

為了解決上面的安全隱患,需要給操作加互斥鎖

@synchronized (self) {
    // 執(zhí)行的操作(需要鎖定的代碼)    
}

// 注意腮猖,鎖定一份代碼秩序一把鎖鉴扫,用多個鎖是無效

互斥鎖的優(yōu)缺點:

  • 優(yōu)點:能有效防止因為多線程搶奪資源造成的資源安全問題
  • 缺點:需要消耗大量CPU資源
    互斥鎖的使用前提:多條線程搶奪同一個資源

線程同步:多條線程在同一條線上執(zhí)行(按順序執(zhí)行任務(wù)) 〕喝保互斥鎖就是使用了線程同步技術(shù)

例子:

// 3個線程創(chuàng)建
self.thread01 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket:) object:@"sale"];
self.thread01.name = @"售票員01";
    
self.thread02 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket:) object:@"sale"];
self.thread02.name = @"售票員02";
    
self.thread03 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket:) object:@"sale"];
self.thread03.name = @"售票員03";
    
self.ticketCount = 100;
// 3個線程開啟
[self.thread01 start];
[self.thread02 start];
[self.thread03 start];
// 未加鎖
- (void)saleTicket:(NSString*)string {
    while (1) {
        NSInteger count = self.ticketCount;
        if (count > 0) {
            self.ticketCount = count - 1;
            NSLog(@"%@賣了一張幔妨,還剩下%zd張",[NSThread currentThread].name,self.ticketCount);
        } else {
            NSLog(@"全部賣完了");
            break;
        }
    }
}
//**********log**************
 售票員01賣了一張鹦赎,還剩下99張
 售票員01賣了一張,還剩下97張
 售票員02賣了一張误堡,還剩下98張
 售票員01賣了一張古话,還剩下96張
 售票員03賣了一張,還剩下95張
 售票員02賣了一張锁施,還剩下93張
 售票員01賣了一張陪踩,還剩下94張
 售票員03賣了一張,還剩下92張
 售票員02賣了一張悉抵,還剩下91張
 售票員01賣了一張肩狂,還剩下90張
 售票員03賣了一張,還剩下89張
 售票員02賣了一張姥饰,還剩下88張
 售票員01賣了一張傻谁,還剩下87張
 售票員03賣了一張,還剩下86張
//***************************
// 加鎖
- (void)saleTicket:(NSString*)string {
    while (1) {
        @synchronized (self) {
            NSInteger count = self.ticketCount;
            if (count > 0) {
                self.ticketCount = count - 1;
                NSLog(@"%@賣了一張列粪,還剩下%zd張",[NSThread currentThread].name,self.ticketCount);
            } else {
                NSLog(@"全部賣完了");
                break;
            }
        }
    }
}
//**********log**************
 售票員01賣了一張审磁,還剩下99張
 售票員01賣了一張,還剩下98張
 售票員02賣了一張岂座,還剩下97張
 售票員01賣了一張态蒂,還剩下96張
 售票員03賣了一張,還剩下95張
 售票員02賣了一張费什,還剩下94張
 售票員01賣了一張钾恢,還剩下93張
 售票員03賣了一張,還剩下92張
 售票員02賣了一張鸳址,還剩下91張
 售票員01賣了一張瘩蚪,還剩下90張
 售票員03賣了一張,還剩下89張
 售票員02賣了一張稿黍,還剩下88張
 售票員01賣了一張募舟,還剩下87張
 售票員03賣了一張,還剩下86張
//***************************
線程之間的通信

體現(xiàn):一個線程給另一個線程傳遞數(shù)據(jù)闻察;在一個線程中執(zhí)行完特定任務(wù)后,裝到另一個線程繼續(xù)執(zhí)行任務(wù)

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"touchesBegan -- ");
    // 開啟子線程
    [NSThread detachNewThreadSelector:@selector(upload) toTarget:self withObject:nil];
}
- (void)upload {
    // 在子線程中執(zhí)行圖片數(shù)據(jù)請求(耗時操作)
    NSString *urlStr = [NSString stringWithFormat:@"https://www.baidu.com/img/bd_logo1.png"];
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlStr]];
    UIImage *image = [UIImage imageWithData:data];
    // 回到主線程   waitUntilDone:是否需要等待主線程完成后在進(jìn)行其他操作
    [self performSelectorOnMainThread:@selector(showImage:) withObject:image waitUntilDone:NO];
    // 回到主線程琢锋,在主線程執(zhí)行self.imageView的setImage操作辕漂,參數(shù)是image
    // [self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO];
    // 回到主線程,在主線程執(zhí)行self.imageView的setImage操作吴超,參數(shù)是image
    // [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
    
}
- (void)showImage:(UIImage*)image {
    self.imageView.image = image;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钉嘹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鲸阻,更是在濱河造成了極大的恐慌跋涣,老刑警劉巖缨睡,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異陈辱,居然都是意外死亡奖年,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門沛贪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來陋守,“玉大人,你說我怎么就攤上這事利赋∷溃” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵媚送,是天一觀的道長中燥。 經(jīng)常有香客問我,道長塘偎,這世上最難降的妖魔是什么疗涉? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮式塌,結(jié)果婚禮上博敬,老公的妹妹穿的比我還像新娘。我一直安慰自己峰尝,他們只是感情好偏窝,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著武学,像睡著了一般祭往。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上火窒,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天硼补,我揣著相機與錄音,去河邊找鬼熏矿。 笑死已骇,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的票编。 我是一名探鬼主播褪储,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼慧域!你這毒婦竟也來了鲤竹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤昔榴,失蹤者是張志新(化名)和其女友劉穎辛藻,沒想到半個月后碘橘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡吱肌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年痘拆,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岩榆。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡错负,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出勇边,到底是詐尸還是另有隱情犹撒,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布粒褒,位于F島的核電站识颊,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏奕坟。R本人自食惡果不足惜祥款,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望月杉。 院中可真熱鬧刃跛,春花似錦、人聲如沸苛萎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腌歉。三九已至蛙酪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間翘盖,已是汗流浹背桂塞。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留馍驯,地道東北人阁危。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像汰瘫,于是被迫代替她去往敵國和親狂打。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容

  • .一.進(jìn)程 進(jìn)程:是指在系統(tǒng)中正在運行的一個應(yīng)用程序,每個進(jìn)程之間是獨立的吟吝,每個進(jìn)程均運行在其專用且受保護(hù)的內(nèi)存空...
    IIronMan閱讀 4,488評論 1 33
  • 學(xué)習(xí)多線程的目的:就是將耗時操作放到后臺去執(zhí)行。 基本概念進(jìn)程? 進(jìn)程是指在系統(tǒng)中正在運行的一個應(yīng)用程序? 每個進(jìn)...
    6ffd6634d577閱讀 587評論 0 1
  • 本文出自 Eddy Wiki 颈娜,轉(zhuǎn)載請注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,128評論 0 14
  • 【JAVA 線程】 線程 進(jìn)程:是一個正在執(zhí)行中的程序剑逃。每一個進(jìn)程執(zhí)行都有一個執(zhí)行順序浙宜。該順序是一個執(zhí)行路徑,或者...
    Rtia閱讀 2,768評論 2 20
  • 房地產(chǎn)銷售話術(shù),銷冠都這么說(二) 我們在地產(chǎn)銷售的時候萤捆,總會遇到各種問題裙品,遇到各種客戶,那么遇到客戶疑問應(yīng)該怎么...
    悠然過客閱讀 611評論 0 0