在java5以前實(shí)現(xiàn)多線程有兩種方法(繼承Thread類和實(shí)現(xiàn)Runnable接口) 它們分別為: 使用new Thread()和new Thread(Runnable)形式 第一種直接調(diào)用thread的run方法,所以,往往使用Thread子類,即new SubThread()。 第二種調(diào)用 Runnable的run方法。 第一種: new Thread(){}.start();這表示調(diào)用Thread子類對(duì)象的run方法,new Thread(){}表示一個(gè)Thread的匿名子類的實(shí)例對(duì)象,子類加上run方法后的代碼如下: new Thread(){ public void run(){ } }.start(); 第二種: new Thread( new Runnable(){} ).start(); 這表示調(diào)用Thread對(duì)象接受的Runnable對(duì)象的run方法,new Runnable(){}表示一個(gè)Runnable的匿名子類的實(shí)例對(duì)象, runnable的子類加上run方法后的代碼如下: new Thread(new Runnable(){ public void run(){ } } ).start();
創(chuàng)新互聯(lián)公司專注于網(wǎng)站建設(shè)|企業(yè)網(wǎng)站維護(hù)|優(yōu)化|托管以及網(wǎng)絡(luò)推廣,積累了大量的網(wǎng)站設(shè)計(jì)與制作經(jīng)驗(yàn),為許多企業(yè)提供了網(wǎng)站定制設(shè)計(jì)服務(wù),案例作品覆蓋水處理設(shè)備等行業(yè)。能根據(jù)企業(yè)所處的行業(yè)與銷售的產(chǎn)品,結(jié)合品牌形象的塑造,量身策劃品質(zhì)網(wǎng)站。
1.goole開源?
2.iOS基礎(chǔ)知識(shí)
;page=1
3.OC的缺陷和陷阱
4.文頂頂博客園
5.FaceBook
6.objc中國(guó)
7.唐巧的技術(shù)博客
8.念茜的博客
9.code4app
10.cocoaChina
11.IT 社區(qū)
12.C博客
13.CocoaPods的安裝及使用
14.標(biāo)準(zhǔn)時(shí)間與時(shí)間戳相互轉(zhuǎn)化
15.博客? loadView、viewDidLoad及viewDidUnload的關(guān)系
16.iOS即時(shí)通訊語音聊天本地音頻處理
17.承影博客
18.常用加密
19.正則表達(dá)式
20.iphone開發(fā)過程中調(diào)試多次release問題?
21.使用 Xcode 和 Instruments 調(diào)試解決 iOS 內(nèi)存泄露
22.iOS開發(fā)中常見的一些bug
23.玩轉(zhuǎn)swift
24.友盟分享
25.objc中國(guó)
26.ViewController的切換
27.iOS 平臺(tái) Cocos2d-x 項(xiàng)目接入新浪微博 SDK 的坑
28.joosonmao的專欄(里面的文章都很棒)
29.移動(dòng)IM(環(huán)信)
環(huán)信XMPP:
30.各種錯(cuò)誤匯總博客園
31.菜鳥筆記
;page=1
32.開發(fā)者賬號(hào)注冊(cè)和支付
33.在Xcode中使用Git進(jìn)行源碼版本控制
34.PNChart(圖像繪畫)
35.微信公眾平臺(tái)
36.常用加密
37.cocoaPod相關(guān)網(wǎng)址:
38.2014年整理的IOS開發(fā)常用庫
39.挺好的一個(gè)網(wǎng)站
40、響應(yīng)者鏈
41、改變UITabBar的背景色
;utm_medium=referral
42、 IOS 集成到支付寶的步驟及問題
43、 XMPP 協(xié)議實(shí)現(xiàn)原理介紹
44、 iOS開發(fā)多線程篇—多線程簡(jiǎn)單介紹
45、KVC 與 KVO理解
46、 iOS 設(shè)計(jì)模式之單例模式
47. 一些第三方庫的了解
線程和進(jìn)程在我們開發(fā)中,跟我們一直形影不離,那么什么是進(jìn)程,什么是線程,它們又有什么關(guān)系,這篇文章將為您簡(jiǎn)單介紹。
線程概念
進(jìn)程概念
地址空間:同?進(jìn)程的線程共享本進(jìn)程的地址空間( TLS是本地的線程棧存空間,線程的局部空間是某些操作系統(tǒng)為線程提供的私有空間,只具備有限的容量,并不屬于線程,由操作系統(tǒng)單獨(dú)安排的 ),?進(jìn)程之間則是獨(dú)?的地址空間。
資源擁有:同?進(jìn)程內(nèi)的線程共享本進(jìn)程的資源如內(nèi)存、I/O、cpu等,但是進(jìn)程之間的資源是獨(dú)?的。
優(yōu)點(diǎn):
缺點(diǎn):
時(shí)間?的概念:CPU在多個(gè)任務(wù)直接進(jìn)?快速的切換,這個(gè)時(shí)間間隔就是時(shí)間?。
多線程同時(shí)執(zhí)行
如果線程非常多
互斥鎖?結(jié)
互斥鎖參數(shù)
nonatomic?原?屬性
atomic原?屬性(線程安全),針對(duì)多線程設(shè)計(jì)的,默認(rèn)值,保證同?時(shí)間只有?個(gè)線程能夠?qū)?(但是同?個(gè)時(shí)間多個(gè)線程都可以取值)
atomic本身就有?把鎖(?旋鎖)
單寫多讀:?jiǎn)蝹€(gè)線程寫?,多個(gè)線程可以讀取
atomic:線程安全,需要消耗?量的資源
nonatomic:?線程安全,適合內(nèi)存?的移動(dòng)設(shè)備
iOS開發(fā)建議
所有屬性都聲明為nonatomic
盡量避免多線程搶奪同一塊資源
盡量將加鎖,資源搶奪的業(yè)務(wù)邏輯交給服務(wù)器處理,減少APP的壓力
這篇文章簡(jiǎn)單介紹了線程與進(jìn)程的概念,煩請(qǐng)大家不吝賜教。
在使用GCD的時(shí)候,我們會(huì)把需要處理的任務(wù)放到Block中,然后將任務(wù) 追加 到相應(yīng)的隊(duì)列里面,這個(gè)隊(duì)列,叫做Dispatch Queue。然而,存在于兩種Dispatch Queue,一種是要等待上一個(gè)執(zhí)行完,再執(zhí)行下一個(gè)的Serial Dispatch Queue,這叫做串行隊(duì)列;另一種,則是不需要上一個(gè)執(zhí)行完,就能執(zhí)行下一個(gè)的Concurrent Dispatch Queue,叫做并行隊(duì)列。這兩種,均遵循FIFO(先進(jìn)先出)原則。
那么,并行隊(duì)列又是怎么在執(zhí)行呢?
雖然可以同時(shí)多個(gè)任務(wù)的處理,但是并行隊(duì)列的處理量,還是要根據(jù)當(dāng)前系統(tǒng)狀態(tài)來。如果當(dāng)前系統(tǒng)狀態(tài)最多處理2個(gè)任務(wù),那么1、2會(huì)排在前面,3什么時(shí)候操作,就看1或者2誰先完成,然后3接在后面。
串行與并行針對(duì)的是隊(duì)列,而同步與異步,針對(duì)的則是線程。 最大的區(qū)別在于,同步線程要阻塞當(dāng)前線程,必須要等待同步線程中的任務(wù)執(zhí)行完,返回以后,才能繼續(xù)執(zhí)行下一任務(wù),整個(gè)過程是不會(huì)創(chuàng)建新線程的;而異步線程則是不用等待,會(huì)在新開啟的線程中執(zhí)行任務(wù)(執(zhí)行主隊(duì)列的任務(wù)除外,主隊(duì)列的任務(wù)在主線程中執(zhí)行)。
分析:
首先執(zhí)行任務(wù)1,這是肯定沒問題的,只是接下來,程序遇到了同步線程,那么它會(huì)進(jìn)入等待,等待任務(wù)2執(zhí)行完,然后執(zhí)行任務(wù)3。但這是隊(duì)列,有任務(wù)來,當(dāng)然會(huì)將任務(wù)加到隊(duì)尾,然后遵循FIFO原則執(zhí)行任務(wù)。那么,現(xiàn)在任務(wù)2就會(huì)被加到最后,任務(wù)3排在了任務(wù)2前面,問題來了:
任務(wù)3要等任務(wù)2執(zhí)行完才能執(zhí)行,任務(wù)2又排在任務(wù)3后面,意味著任務(wù)2要在任務(wù)3執(zhí)行完才能執(zhí)行,所以他們進(jìn)入了互相等待的局面?!炯热贿@樣,那干脆就卡在這里吧】這就是死鎖。
分析:
首先執(zhí)行任務(wù)1,接下來會(huì)遇到一個(gè)同步線程,程序會(huì)進(jìn)入等待。等待任務(wù)2執(zhí)行完成以后,才能繼續(xù)執(zhí)行任務(wù)3。從 dispatch_get_global_queue 可以看出,任務(wù)2被加入到了全局的并行隊(duì)列中,當(dāng)并行隊(duì)列執(zhí)行完任務(wù)2以后,返回到主隊(duì)列,繼續(xù)執(zhí)行任務(wù)3。
分析:
這個(gè)案例沒有使用系統(tǒng)提供的串行或并行隊(duì)列,而是自己通過 dispatch_queue_create 函數(shù)創(chuàng)建了一個(gè) DISPATCH_QUEUE_SERIAL 的串行隊(duì)列。執(zhí)行任務(wù)1;遇到異步線程,將【任務(wù)2、同步線程、任務(wù)4】加入串行隊(duì)列中。因?yàn)槭钱惒骄€程,所以在主線程中的任務(wù)5不必等待異步線程中的所有任務(wù)完成;因?yàn)槿蝿?wù)5不必等待,所以2和5的輸出順序不能確定;任務(wù)2執(zhí)行完以后,遇到同步線程,這時(shí),將任務(wù)3加入串行隊(duì)列;又因?yàn)槿蝿?wù)4比任務(wù)3早加入串行隊(duì)列,所以,任務(wù)3要等待任務(wù)4完成以后,才能執(zhí)行。但是任務(wù)3所在的同步線程會(huì)阻塞,所以任務(wù)4必須等任務(wù)3執(zhí)行完以后再執(zhí)行。這就又陷入了無限的等待中,造成死鎖。
分析:
首先,將【任務(wù)1、異步線程、任務(wù)5】加入Main Queue中,異步線程中的任務(wù)是:【任務(wù)2、同步線程、任務(wù)4】。所以,先執(zhí)行任務(wù)1,然后將異步線程中的任務(wù)加入到Global Queue中,因?yàn)楫惒骄€程,所以任務(wù)5不用等待,結(jié)果就是2和5的輸出順序不一定。然后再看異步線程中的任務(wù)執(zhí)行順序。任務(wù)2執(zhí)行完以后,遇到同步線程。將同步線程中的任務(wù)加入到Main Queue中,這時(shí)加入的任務(wù)3在任務(wù)5的后面。當(dāng)任務(wù)3執(zhí)行完以后,沒有了阻塞,程序繼續(xù)執(zhí)行任務(wù)4。
分析:
和上面幾個(gè)案例的分析類似,先來看看都有哪些任務(wù)加入了Main Queue:【異步線程、任務(wù)4、死循環(huán)、任務(wù)5】。在加入到Global Queue異步線程中的任務(wù)有:【任務(wù)1、同步線程、任務(wù)3】。第一個(gè)就是異步線程,任務(wù)4不用等待,所以結(jié)果任務(wù)1和任務(wù)4順序不一定。任務(wù)4完成后,程序進(jìn)入死循環(huán),Main Queue阻塞。但是加入到Global Queue的異步線程不受影響,繼續(xù)執(zhí)行任務(wù)1后面的同步線程。同步線程中,將任務(wù)2加入到了主線程,并且,任務(wù)3等待任務(wù)2完成以后才能執(zhí)行。這時(shí)的主線程,已經(jīng)被死循環(huán)阻塞了。所以任務(wù)2無法執(zhí)行,當(dāng)然任務(wù)3也無法執(zhí)行,在死循環(huán)后的任務(wù)5也不會(huì)執(zhí)行。
線程的不安全是由于多線程訪問和修改共享資源而引起的不可預(yù)測(cè)的結(jié)果。
ios多線程開發(fā)中為保證線程的安全常用到的幾種鎖: NSLock 、 dispatch_semaphore 、 NSCondition 、 NSRecursiveLock 、 @synchronized 。
WEAKSELF typeof(self) __weak weakSelf = self;
NSLock 是OC層封裝底層線程操作來實(shí)現(xiàn)的一種鎖,繼承NSLocking協(xié)議。不能迭代加鎖,如果發(fā)生兩次lock,而未unlock過,則會(huì)產(chǎn)生死鎖問題。
以車站購(gòu)票為例,多個(gè)窗口同時(shí)售票(同步),每個(gè)窗口有人循環(huán)購(gòu)票:
原子操作
原子操作是指不可打斷的操作,也就是說線程在執(zhí)行操作的過程中,不會(huì)被操作系統(tǒng)掛起,而是一定會(huì)執(zhí)行完,
變量屬性Property中的原子定義
一般我們定義一個(gè)變量@property (nonatomic ,strong)NSLock *lock;nonatomic:非原子性,不會(huì)為setter方法加鎖,適合內(nèi)存小的移動(dòng)設(shè)備;atomic:原子性,默認(rèn)為setter方法加鎖(默認(rèn)就是atomic),線程安全。
PS: 在iOS開發(fā)過程中,一般都將屬性聲明為nonatomic,盡量避免多線程搶奪同一資源,盡量將加鎖等資源搶奪業(yè)務(wù)交給服務(wù)器。
NSCondition常用于生產(chǎn)者-消費(fèi)者模式,它繼承了NSLocking協(xié)議,同樣有l(wèi)ock和unlock方法。條件變量有點(diǎn)像信號(hào)量,提供了線程阻塞和信號(hào)機(jī)制,因此可以用來阻塞某個(gè)線程,并等待數(shù)據(jù)就緒再喚醒程序。
信號(hào)量主要有3個(gè)函數(shù),分別是:
注意: 正常的使用順序是先降低然后提高,這兩個(gè)函數(shù)通常都是成對(duì)出現(xiàn)。
本文主要參考了這篇文章(
),并對(duì)其中所能理解的部分進(jìn)行一一驗(yàn)證,以前沒怎么寫過類似的,如果有什么做的不好的地方還請(qǐng)大家多多見諒!
在多線程開發(fā)中,我們常用到GCD,這里探討一下GCD任務(wù)的取消:
1.在iOS 8以后,系統(tǒng)給我們提供了這樣的取消函數(shù) dispatch_block_cancel,不過這個(gè)也只能用于dispatch_block_create創(chuàng)建的dispatch_block_t,我們?cè)囼?yàn)一下:
這時(shí)肯定是任務(wù)都會(huì)執(zhí)行的
接下來,把注釋的那一行 dispatch_block_cancel(block1);打開,看看效果:
我們發(fā)現(xiàn)block1確實(shí)被取消掉了。這是dispatch_block_cancel的用法。
2.很多時(shí)候,我們的場(chǎng)景不會(huì)去用dispatch_block_create創(chuàng)建dispatch_block_t,這個(gè)時(shí)候我們?nèi)粝肴∠粋€(gè)任務(wù),可以考慮用一個(gè)條件來做,滿足條件則執(zhí)行此任務(wù),不滿足則不執(zhí)行,舉個(gè)例子:
效果如下:
寫到這里,這兒其實(shí)還隱藏了一個(gè)知識(shí)點(diǎn),就是block的變量捕獲,有興趣或是不理解的朋友可以研究一下。(如下,為何輸出不是20而是10)
3.過渡到NSOperation
NSOperation是對(duì)GCD的封裝,底層也是GCD。
NSOperation給我們封裝了更多的api,這是我在Xcode中提出來的:
我們可以發(fā)現(xiàn)它有狀態(tài)屬性,有取消方法,也有添加依賴方法等...這里我們還是先說取消吧,下面來給大家寫個(gè)demo:
這時(shí)輸出是:
因?yàn)檎趫?zhí)行的任務(wù),NSOperation也是不能取消的,所以也是需要將cancel在start前調(diào)用的(就如同滿足一個(gè)條件是否需要cancel一樣,也可以滿足條件不調(diào)用start)
標(biāo)題名稱:ios開發(fā)多線程開發(fā),ios多線程有幾種實(shí)現(xiàn)方法
本文地址:http://m.rwnh.cn/article0/phpooo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、網(wǎng)站設(shè)計(jì)公司、小程序開發(fā)、網(wǎng)站維護(hù)、網(wǎng)站內(nèi)鏈、手機(jī)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)