synchronized 詳解

關于synchronized

問題:
1嗤栓、鎖是如何和與你傳入的@synchronized的對象關聯(lián)上的?
2遮咖、@synchronized 會保持(retain, 增加引用計數(shù))被鎖住的對象嗎熬拒?
3非春、假如你傳入@synchronized的對象在@synchronized的block里面被釋放或者被賦值為nil 將會怎么樣?

#偽代碼:
@synchronized(obj) {
    // do work
}

@try {
    objc_sync_enter(obj);
    // do work
} @finally {
    objc_sync_exit(obj);
}

#使用到的數(shù)據(jù)結(jié)構(gòu)
typedef struct SyncData {
    id object;
    recursive_mutex_t mutex;
    struct SyncData* nextData;
    int threadCount;
} SyncData;

typedef struct SyncList {
    SyncData *data;
    spinlock_t lock;
} SyncList;

// Use multiple parallel lists to decrease contention among unrelated objects.
#define COUNT 16
#define HASH(obj) ((((uintptr_t)(obj)) >> 5) & (COUNT - 1))
#define LOCK_FOR_OBJ(obj) sDataLists[HASH(obj)].lock
#define LIST_FOR_OBJ(obj) sDataLists[HASH(obj)].data
static SyncList sDataLists[COUNT];

當你調(diào)用 objc_sync_enter(obj) 時雹食,它用 obj 內(nèi)存地址的哈希值查找合適的 SyncData畜普,然后將其上鎖。當你調(diào)用 objc_sync_exit(obj) 時群叶,它查找合適的 SyncData 并將其解鎖吃挑。

objc_sync_enter 源碼
int objc_sync_enter(id obj)
{
    int result = OBJC_SYNC_SUCCESS;

    if (obj) {
        SyncData* data = id2data(obj, ACQUIRE);
        require_action_string(data != NULL, done, result = OBJC_SYNC_NOT_INITIALIZED, "id2data failed");
    
        result = recursive_mutex_lock(&data->mutex);
        require_noerr_string(result, done, "mutex_lock failed");
    } else {
        // @synchronized(nil) does nothing
        if (DebugNilSync) {
            _objc_inform("NIL SYNC DEBUG: @synchronized(nil); set a breakpoint on objc_sync_nil to debug");
        }
        objc_sync_nil();
    }

done: 
    return result;
}

回答:
1、你調(diào)用synchronized 的每個對象街立,OC runtime都會為其分配一個遞歸鎖并存在哈希表中舶衬。
2、如果在synchronized 內(nèi)部對象被釋放或被設為nil赎离,看起來都OK逛犹。
3、注意不要向你的 synchronized block 傳nil梁剔,這將會從代碼中移走線程安全

synchronized 詳解

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末虽画,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子荣病,更是在濱河造成了極大的恐慌码撰,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件个盆,死亡現(xiàn)場離奇詭異脖岛,居然都是意外死亡,警方通過查閱死者的電腦和手機砾省,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門鸡岗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人编兄,你說我怎么就攤上這事轩性。” “怎么了狠鸳?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵揣苏,是天一觀的道長。 經(jīng)常有香客問我件舵,道長卸察,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任铅祸,我火速辦了婚禮坑质,結(jié)果婚禮上合武,老公的妹妹穿的比我還像新娘。我一直安慰自己涡扼,他們只是感情好稼跳,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吃沪,像睡著了一般汤善。 火紅的嫁衣襯著肌膚如雪票彪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天垮耳,我揣著相機與錄音,去河邊找鬼铃彰。 笑死牙捉,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的带到。 我是一名探鬼主播揽惹,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼闪金,長吁一口氣:“原來是場噩夢啊……” “哼囱嫩!你這毒婦竟也來了挠说?” 一聲冷哼從身側(cè)響起蛙奖,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤攒砖,失蹤者是張志新(化名)和其女友劉穎吹艇,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年醉拓,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鱼辙。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡廉嚼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出倒戏,到底是詐尸還是另有隱情怠噪,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布杜跷,位于F島的核電站傍念,受9級特大地震影響矫夷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜憋槐,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一双藕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阳仔,春花似錦忧陪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至评矩,卻和暖如春叶堆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背斥杜。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工虱颗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蔗喂。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓忘渔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親缰儿。 傳聞我的和親對象是個殘疾皇子辨萍,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

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