久久久精品一区ed2k-女人被男人叉到高潮的视频-中文字幕乱码一区久久麻豆樱花-俄罗斯熟妇真实视频

iOS使用多線程提高數(shù)據(jù)并發(fā)訪問之七

活躍性

在雞澤等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供網(wǎng)站制作、做網(wǎng)站 網(wǎng)站設(shè)計制作按需搭建網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),網(wǎng)絡(luò)營銷推廣,成都外貿(mào)網(wǎng)站制作,雞澤網(wǎng)站建設(shè)費(fèi)用合理。

活躍性是指好的事情最終會發(fā)生。例如,如果你代碼的目標(biāo)是確保你能夠持續(xù)從數(shù)組中push和pop對象,問題是這個過程是否能夠永遠(yuǎn)工作。使用鎖帶來的問題是鎖會引起系統(tǒng)中所有線程一直等待 -- 換句話說,就是死鎖。如果你能保證你應(yīng)用的活躍性,那么死鎖應(yīng)該永遠(yuǎn)都不會發(fā)生。

問題

想象你有兩個線程:A和B。在Astart之前,A一直等待B結(jié)束。但是,在線程B繼續(xù)運(yùn)行之前,B一直等待線程A結(jié)束。

對于一個實際的例子,你可以在Listing 6-7中查看它的代碼。注意push和pop線程被同一對象鎖住,即lockedObj。圖6-7顯示了這兩個線程是如何在同一個對象上鎖住,并永遠(yuǎn)的互相等待。

iOS使用多線程提高數(shù)據(jù)并發(fā)訪問 之七

在新的例子中你可以看到,pop線程一直在while循環(huán)上等待,因為storages數(shù)組的大小為0。同時push線程不能往數(shù)組中添加對象,因為代碼被對象lockedObj鎖住了。push線程現(xiàn)在必須等待pop線程執(zhí)行完,然后把鎖歸還給lockedObj對象。因此,這兩個線程停止,然后永遠(yuǎn)的等待對方。這里有一些死鎖問題的解決辦法。

如果你的代碼發(fā)生了死鎖,你不能再使用@synchronized(lockedObj),因為這樣直接使用是不能避免死鎖的。

  • NSLock:你可以使用它來保護(hù)并發(fā)訪問的代碼塊,就像使用@synchronized(obj)那樣,但是當(dāng)這部分代碼lock和unlock時,你能夠控制它。

  • NSCondition:這對于生產(chǎn)者和消費(fèi)者模式是非常有用的,就像前面顯示的push和pop這個例子。

NSLock 解決辦法

你可以有兩種使用方式,lock或tryLock。使用lock的方法,這個方法不能在獲取鎖,它會停止,然后等待直到它獲取到鎖。使用tryLock,如果方法返回NO,意味著鎖已經(jīng)被其他線程占有,調(diào)用的線程不能獲取它。

iOS使用多線程提高數(shù)據(jù)并發(fā)訪問 之七

它已經(jīng)測試了,如果獲取到鎖就繼續(xù)執(zhí)行。如果你沒有獲取到鎖,一切正常,線程會繼續(xù)執(zhí)行其他沒有使用鎖的代碼。

NSCondition 解決辦法

使用NSLock,你會看到通過使用[testLock lock]來獲取一個鎖;你不能停止或掛起你的線程來等待一些條件。你唯一能做的就是繼續(xù)執(zhí)行直到你釋放鎖,這樣其他線程才能獲取鎖執(zhí)行。

再看看push,pop這個例子。讓線程不停的運(yùn)行檢查數(shù)組是否有數(shù)據(jù),效率是不高的。在循環(huán)中,如果線程發(fā)現(xiàn)數(shù)組中沒有數(shù)據(jù),它應(yīng)該停止然后等待數(shù)組有數(shù)據(jù)了,就把它給取出來。這種方法的好處是你能夠掛起你的線程,而不會浪費(fèi)系統(tǒng)的資源。

為了讓一個線程停止,等待,還有同時返回一個鎖,你需要使用NSCondition。Listing 6-8 演示了如何使用NSCondition來執(zhí)行push,pop這個例子。

iOS使用多線程提高數(shù)據(jù)并發(fā)訪問 之七

還有其他的鎖機(jī)制,如NSRecursiveLock和NSConditionLock,但是使用NSLock和NSCondition在大部分情況下就足夠了。對于線程,你應(yīng)該總是簡單明了,因為多線程會在你的代碼中引入不確定的bug。

注意:NSRecursiveLock是非常有用的,如果你有一個線程想要多次獲取一個鎖,而又不會發(fā)生死鎖的話。NSRecursiveLock依然會阻塞其他線程來訪問代碼塊。

死鎖

使用鎖可能會導(dǎo)致死鎖的發(fā)生。死鎖就像前面介紹的那樣,但是更多的情況是,有兩個或多個鎖時,然后線程之間相互等待。

圖6-8演示了線程1獲取object1對象鎖和線程2獲取object2對象鎖的解決辦法。然后線程1想要獲取object2的鎖,但是必須等待線程2釋放這個鎖。同時,線程2想要獲取object1的鎖,但是必須等待線程1釋放這個鎖。正如你看到的,兩個線程互相等待,沒有一個能繼續(xù)運(yùn)行。

iOS使用多線程提高數(shù)據(jù)并發(fā)訪問 之七

有一些方法能夠解決死鎖問題,比如reordering threads;minimize locking;a bigger lock;tryLock;time out for locking。這些機(jī)制都不難實現(xiàn);下面的這些圖能夠幫助你理解他們是如何工作的。

在圖6-9中,最簡單的方式就是對線程重排序,然后順序鎖定,這樣只有當(dāng)一個使用lock2的線程結(jié)束時,其他線程才能獲取鎖,然后繼續(xù)執(zhí)行。

但是,如果你的方法結(jié)構(gòu)是固定的,有一些代碼是屬于第三方庫,很難重排序鎖或修改代碼。

iOS使用多線程提高數(shù)據(jù)并發(fā)訪問 之七

接下里的一種方法是只有你確實需要鎖住的那部分才嘗試鎖住。這中方法使的鎖住的部分最小,如圖6-10.

iOS使用多線程提高數(shù)據(jù)并發(fā)訪問 之七

如果有代碼或想把你不需要鎖住的代碼單獨(dú)分離出來,這種方式是很容易實現(xiàn)的。注意它會使你的代碼變得更復(fù)雜。

另外一種方法是,在其他鎖上實現(xiàn)另外一個更大的鎖。這允許其他線程嘗試同時訪問同樣的鎖。例如,在圖6-11中,由于一個新的更大的鎖,線程2現(xiàn)在必須等待線程1完成,在它能獲取其他鎖或運(yùn)行必要的代碼之前。在正常的代碼中,如果能夠從更小的鎖中移除,用更大的鎖取代,你應(yīng)該這樣做,當(dāng)它能夠減少代碼的復(fù)雜性時。這種機(jī)制通常使用在,當(dāng)你需要在庫(你不能或不想修改庫中的代碼)中防止死鎖時。

iOS使用多線程提高數(shù)據(jù)并發(fā)訪問 之七

你應(yīng)該嘗試使用tryLock。使用tryLock,如果一個線程不能獲取到鎖,它不會停止和等待。線程能夠繼續(xù)執(zhí)行線程中的其他代碼。這是一個使用tryLock的例子:

iOS使用多線程提高數(shù)據(jù)并發(fā)訪問 之七

我介紹的最后一種方法是使用超時,盡管還有很多其他的方法來防止死鎖。在objective-c中,你可以指定線程來等待,直到你能獲取到鎖或需要等待結(jié)束的時間。使用lockBeforeDate方法能幫助你達(dá)到這個目的。調(diào)用這個方法的線程將會阻塞直到你能獲取到鎖。如果參數(shù)中指定的NSDate實例發(fā)生了,但是線程還沒有獲取到鎖,它會繼續(xù)執(zhí)行。這在死鎖時會有幫助;你的線程能夠繼續(xù)執(zhí)行,這可能會有一些小的風(fēng)險,但是不可能發(fā)生死鎖。

當(dāng)前名稱:iOS使用多線程提高數(shù)據(jù)并發(fā)訪問之七
文章轉(zhuǎn)載:http://sd-ha.com/article42/joschc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、云服務(wù)器、外貿(mào)網(wǎng)站建設(shè)、虛擬主機(jī)、網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)