NSThread官方文檔

  • Threads的替代方案:

    • Operation Objects:是一個(gè)任務(wù)包裝器,這個(gè)會(huì)在非主線程執(zhí)行。這個(gè)包裝器隱藏了線程管理的細(xì)節(jié)吮播,讓用戶可以專注在線程本身上。
    • GCD眼俊,GCD可以比用thread更高效的執(zhí)行任務(wù)意狠。
    • Idle-time notifications:對(duì)于優(yōu)先級(jí)非常低的任務(wù),可以考慮使用Idle-time notification疮胖。
  • 線程在時(shí)間上和空間上創(chuàng)建是需要代價(jià)的摄职,所以推薦在線程中去做非常多的重要工作或者建立run loop以允許復(fù)用一些顯示任務(wù)誊役。

  • Run loop是一片管理事件異步到達(dá)線程的基礎(chǔ)設(shè)施。

  • 以下是保證你代碼正確性的實(shí)現(xiàn)線程的一些方法:

    • 避免明確的建立線程谷市。預(yù)期手動(dòng)建立線程,不妨嘗試使用異步API击孩,GCD迫悠,operation objects來(lái)完成工作。
    • 保持線程的忙碌:你應(yīng)該確保分配給線程的人物是長(zhǎng)周期的巩梢、多產(chǎn)的(不要浪費(fèi)).
    • 避免共享數(shù)據(jù)結(jié)構(gòu):最簡(jiǎn)單的避免線程相關(guān)資源沖突的方法是給每一個(gè)線程它需要資源的copy创泄。平行代碼在線程間最小化通信以及溝通時(shí)效率達(dá)到最大。
    • 推薦在主線程去接收用戶相關(guān)的事件和初始化UI括蝠。
    • 留意在退出時(shí)的線程行為:進(jìn)程只有在非分派的線程退出時(shí)才會(huì)停止鞠抑。如果你在編寫CoCoa應(yīng)用,你應(yīng)當(dāng)使用applicationShouldTerminate:delegate方法去使得app在一段時(shí)間之后終止或者一起取消掉忌警。
    • 處理Exceptions:一些情況下搁拙,exception處理這也許會(huì)被自動(dòng)創(chuàng)建,例如法绵,@synchronized標(biāo)簽就會(huì)默認(rèn)包含exception 處理器箕速。
    • 干凈地終止你的線程。最佳的退出線程的方法就是讓它自然退出朋譬,讓它達(dá)到主鏈路的終點(diǎn)盐茎。
    • 在Libraries中保證線程安全:對(duì)于Libraries 開(kāi)發(fā)者,不能只在app變成多線程時(shí)創(chuàng)建locks徙赢。如果要在某個(gè)線程中l(wèi)ock字柠,最好用libraries之前創(chuàng)建,推薦在創(chuàng)建library之前就用locks狡赐。切記Lock和unlock一定要配對(duì)窑业。在使 * 用Cocoa library時(shí),最好注冊(cè)一個(gè)觀察者接收NSwillBecomMuliThreadedNotification阴汇,這樣就在application變成多線程時(shí)接收到了通知数冬。
  • 線程創(chuàng)建消耗:

    • Kernal 數(shù)據(jù)結(jié)構(gòu):大概1KB
    • 棧空間:512KB(非主線程);1MB(主線程)搀庶。最小的非主線程椆丈矗空間是16KB,并且棧空間必須是4KB的倍數(shù)哥倔。
    • Creation時(shí)間:大概90毫秒秸架。
    • 另一個(gè)消耗是成品消耗。所以說(shuō)咆蒿,應(yīng)當(dāng)盡量避免使用同步东抹,而且等待locks或者不作為更浪費(fèi)時(shí)間蚂子。
  • 如果你有正在運(yùn)行的NSThread對(duì)象的化,一種可以send消息的方法是使用performSelector:onThread:withObject:waitUntileDone:方法缭黔。

  • 設(shè)置線程的検尘ィ空間。在Cocoa下馏谨,在調(diào)用start方法之前别渔,使用setStackSize:方法來(lái)制定stack的size。

  • 配置Thread-Local的存儲(chǔ)惧互。在Cocoa下哎媚,你可以使用NSThread對(duì)象的threadDictionary方法去接收一個(gè)NSMutableDictionary對(duì)象,理論上就可以給thread添加任何keys了喊儡。

  • 一般情況下拨与,將thread保留在其默認(rèn)值上。Cocoa Threads艾猜,你可以使用setThreadPriority:類方法(NSThread)來(lái)設(shè)置當(dāng)前運(yùn)行線程的優(yōu)先級(jí)买喧。

  • 創(chuàng)建Autorelease Pool:如果一個(gè)app使用GC,而不是內(nèi)存管理模型箩朴,則創(chuàng)建autorelease pool并不是必須的岗喉。Autorelease pool在GC下并無(wú)害,但是大部分都會(huì)被忽略炸庞。Autorelease pool必須要支持managed model code钱床,并且如果app 運(yùn)行在gc下時(shí)會(huì)非常容易被忽略。所以如果你的app是運(yùn)行在managed memory model下埠居,創(chuàng)建一個(gè)autorelease pool應(yīng)當(dāng)是最先在thread實(shí)體路徑中做的事兒查牌。類似的,destory這個(gè)autorelease pool是在這個(gè)thread中最后一個(gè)要做的事滥壕。

  • 因?yàn)閠op-level的autorelease pool在thread退出之前不會(huì)釋放它包含的對(duì)象纸颜,所以long-lived的thread應(yīng)當(dāng)新建額外的autorelease pool,去更頻繁的釋放對(duì)象绎橘。

  • 當(dāng)你想運(yùn)行在不同的線程上時(shí),你有兩個(gè)選項(xiàng):第一個(gè)選項(xiàng)是將代碼寫在一個(gè)長(zhǎng)的task上称鳞,并且?guī)缀醪槐恢袛啵Y(jié)束時(shí)終止線程冈止;另一個(gè)選項(xiàng)是將線程放到一個(gè)loop中,在到達(dá)時(shí)動(dòng)態(tài)的執(zhí)行請(qǐng)求熙暴,這種方法需要建立這個(gè)線程的run loop.

  • 終止線程:推薦的終止線程的方法是讓它自然的退出慌盯。雖然有killing方法掂器,但是嚴(yán)重不推薦使用。如果需要中途去終止一個(gè)線程唉匾,需要設(shè)計(jì)線程去從外部響應(yīng)cancel或者退出消息。對(duì)于長(zhǎng)線的操作,需要定期檢查是否有需要終止的線程芋簿。一種方式去取消msg是使用一個(gè)run loop 輸入源去接受這樣的msg。

while(moreWorkToDo && !exitNoew)
{
  runLoop runUntilDate:[NSDate date];
  exitNow =[ [threadDict valueForKey:@”ThreadShouldExitNow”] boolValue];
}
  • Run loop的目的是當(dāng)有工作要做時(shí)与斤,保持線程busy;當(dāng)沒(méi)有工作可做時(shí)讓線程sleep撩穿。Runloop,字如其名食寡,就是一個(gè)可以運(yùn)行事件處理器的loop,并且這個(gè)loop可以響應(yīng)未來(lái)的事件抵皱。

  • Runloop接收兩種不同類型的源善榛,一種是Input source,傳遞異步事件呻畸,接收自完全不同的application或者其它thread移盆;另一種是Timer source,傳遞同步事件伤为,在一個(gè)計(jì)劃好的時(shí)間或者重復(fù)的interval中出現(xiàn)咒循。

  • 如上圖所示,input source會(huì)傳遞異步事件給響應(yīng)的處理函數(shù)并且觸發(fā)runUntilDate:方法來(lái)退出绞愚。 Timer source將事件傳遞到handler路徑上但是并不導(dǎo)致run loop退出叙甸。

  • 除了處理input source之外,run loop還能生成關(guān)于run loop行為的通知爽醋。 注冊(cè) run-loop的觀察者可以接收這些通知蚁署,并且可以在線程上做一些額外的操作。

  • Run Loop的Modes:run loop的mode是input sources和需要監(jiān)聽(tīng)的集合蚂四,也是需要被通知的觀察者的集合光戈。每次運(yùn)行run loop時(shí)哪痰,你都指定了一種特殊的mode去運(yùn)行。傳給run loop之后久妆,只有符合mode條件的source才會(huì)被監(jiān)視和被允許傳遞事件晌杰。

  • Mode是用來(lái)從那些不想要的source中篩選出需要的sources。大部分時(shí)間筷弦,你會(huì)希望run loop運(yùn)行在default mode下肋演。一個(gè)模態(tài)面板,也許會(huì)運(yùn)行在“模態(tài)”模式下烂琴。在這種模式下爹殊,只有相關(guān)的source才會(huì)傳遞到那個(gè)thread上。對(duì)于非主線程而言奸绷,你也許使用custom modes來(lái)防止通過(guò)非常重要的實(shí)時(shí)的操作去傳遞低優(yōu)先級(jí)源梗夸。

  • 定義好的run loop modes:

    • Default:NSDefaultRunloopMode,默認(rèn)通過(guò)這個(gè)mode去配置和執(zhí)行你的input sources
    • Connection:NSConnectionReplyMode号醉,這個(gè)很少用反症,用來(lái)倆節(jié)NSConnection對(duì)象以監(jiān)聽(tīng)回應(yīng)。
    • Modal:NSModalPanelRunLoopMode畔派,Cocoa使用這個(gè)Mode來(lái)識(shí)別為了modal panel而用的事件。
    • Event tracking:NSEventTrackingRunLoopMode胞谈,Cocoa使用這個(gè)mode去限制輸入事件呜魄,尤其在mouse-dragging loops或者其它類型的ui tracking loops中爵嗅。
    • Common modes:NSRunLoopCommonModes笨蚁,這個(gè)modes是常用mode的集合。對(duì)于Cocoa 應(yīng)用伪很,這個(gè)集合包括default锉试,modal呆盖,和event tracking mode。 CoreFoundation 默認(rèn)包含default mode宙项,你可以添加custom modes 通過(guò)set CFRunLoopAddCommonMode函數(shù)來(lái)完成株扛。
    • Input source: 輸入源會(huì)將事件異步的傳遞到你的線程中洞就。只要你的run loop建立了連接,input-source 是port-based還是custom就無(wú)所謂了改基。兩種類型唯一的區(qū)別就是被通知的方式不同。Port-based是通過(guò)kernal自動(dòng)的通知躁染,而custom source必須手動(dòng)通過(guò)其它線程來(lái)通知吞彤。
    • Port-based Source: Cocoa和Core Fundation提供了內(nèi)置的創(chuàng)建port-based 輸入源的支持叹放,通過(guò)使用port-related 對(duì)象和函數(shù)井仰。在Core Foundation里俱恶,你必須手動(dòng)創(chuàng)建ports和它的run loop source.
    • Custom Input Source: 創(chuàng)建一個(gè)custom input source,你必須使用和CFRunLoopSourceRef相關(guān)聯(lián)的function了罪。
    • Cocoa Perform Selector Source:Cocoa定義了custom input source泊藕,允許你在任何線程上去執(zhí)行selector娃圆。當(dāng)selector執(zhí)行完畢,selector source會(huì)將自己從run loop中移除景醇。
  • Run Loop的事件執(zhí)行順序:

    • 通知已經(jīng)進(jìn)入run loop的observer
    • 通知那些timer準(zhǔn)備觸發(fā)的observer
    • 通知那些不基于port的準(zhǔn)備觸發(fā)的input source的observer
    • 觸發(fā)所有不基于port的input source
    • 如果一個(gè)port-based 輸入源準(zhǔn)備好并等待fire三痰,則事件會(huì)立即執(zhí)行窜管。執(zhí)行第九步幕帆。
    • 通知那些馬上要sleep的thread的observer
    • 將thread帶入到sleep,除非:
      i.一個(gè)基于port的input source事件來(lái)了
      ii. Timer觸發(fā)了
      iii. Run loop被叫醒了
    • 通知observers常熙,thread已經(jīng)醒了
    • 執(zhí)行進(jìn)行中的event
    • 如果用戶定義的timer出發(fā)了裸卫,執(zhí)行timer事件并且重啟loop墓贿,跳到第二步
    • 如果input source 觸發(fā)了聋袋,傳遞事件
    • 如果run loop醒了但是沒(méi)有超時(shí)幽勒,重啟loop刀荒,跳到第二步
  • 通知observer缠借,runloop退出了泼返。

  • 如果這些events中間的時(shí)間非常寶貴,那么你可以使用sleep和awak-from-sleep通知來(lái)幫助你關(guān)聯(lián)這些真實(shí)事件之間的時(shí)間叫乌。

  • 什么時(shí)候應(yīng)當(dāng)使用run loop憨奸? 只有在你為你的應(yīng)用創(chuàng)建非主線程的時(shí)候運(yùn)行一個(gè)run loop凿试。在非主線程上那婉,你應(yīng)當(dāng)決定是否應(yīng)該使用run loop详炬。如果應(yīng)該,則自己配置并且start在跳。你不應(yīng)該start 一個(gè)線程的run loop硬毕,什么時(shí)候都不應(yīng)該礼仗。

  • 如果你想做下列事情元践,你應(yīng)該去start一個(gè)run loop:

    • 使用ports或者custom input source去和其它線程交流
    • 在thread上使用timer
    • 在Cocoa application上使用performSelector…
    • 讓線程去執(zhí)行間歇性的tasks
  • 停止一個(gè)線程单旁,最好讓它自然停止象浑,而不是強(qiáng)制終止愉豺。

  • Start一個(gè)run loop:start一個(gè)run loop只有在你的app里的非主線程中才有必要蚪拦。一個(gè)run loop必須至少有一個(gè)input source或者timer來(lái)監(jiān)聽(tīng)驰贷。

  • 有幾種方法可以start一個(gè)run loop,包括:

    • 無(wú)條件的
    • 設(shè)置一個(gè)時(shí)間限制
    • 在特殊的mode中
  • 無(wú)條件的運(yùn)行你的run loop指的是將thread放到一個(gè)永恒的loop中次兆,你會(huì)獲得非常有限的控制run loop的權(quán)利芥炭。你可以添加或者刪除input source或者timer蚤认,但是stop這個(gè)run loop的唯一方式就是kill掉它砰琢。沒(méi)辦法在custom mode下運(yùn)行run loop陪汽。

  • 與無(wú)條件運(yùn)行run loop相比挚冤,給一個(gè)時(shí)間限制更好赞庶。

  • 退出run loop:有兩種方法可以在運(yùn)行一個(gè)事件前使得run loop退出歧强,分別是:

    • 給一個(gè)timeout值
    • 告訴run loop停止。
    • 其中肤京,給一個(gè)timeout值是推薦的忘分,前提是你可以管理它妒峦。
    • 其次舟山,雖然移除run loop的input source和timers也許也能導(dǎo)致run loop退出,但是這不是一個(gè)停止run loop的可靠的方法寒矿。
  • Cocoa NSRunLoop雷并不像Core Foundation副本一樣符相,是一個(gè)線程安全的蠢琳。

  • 同步方法:

    • Atomic Operations:原子操作指的是一些形式簡(jiǎn)單的同步,以簡(jiǎn)單的數(shù)據(jù)類型為媒介蓝牲。原子操作的優(yōu)勢(shì)是他們不會(huì)block或者競(jìng)爭(zhēng)資源例衍。
    • Memory Barriers 是一種非block型同步工具佛玄,通常用來(lái)確保memory操作以正確的順序執(zhí)行累澡。
    • Locks:可以使用Locks來(lái)保護(hù)code的重要部分愧哟,以確保在同一個(gè)時(shí)間段只有一個(gè)代碼段可以被執(zhí)行。
  • Lock類型有:

    • Mutex:是一種確保某時(shí)間只有一個(gè)thread可以運(yùn)行的信號(hào)量圈驼。
    • Recursive lock:recursive lock主要用在遞歸操作之中,但是也會(huì)用在多個(gè)線程中每一個(gè)線程都分別需要同一個(gè)lock的情況橄抹。
    • Read-write lock:這種lock可以用在大范圍的操作中楼誓,而且可以顯著的提高性能名挥,尤其當(dāng)保護(hù)的數(shù)據(jù)結(jié)構(gòu)經(jīng)常被讀但是偶爾被寫。(POSIX ONLY)
  • Conditions:Conditions最常用在確定資源是否可用或者確保tasks以一種特定order呈現(xiàn)参淫。當(dāng)一個(gè)thread tests 一個(gè)condition愧杯,它只會(huì)讓condition為ture的運(yùn)行力九,否則block跌前。Condition和mutex lock之間的區(qū)別在于多線程有可能在同一時(shí)間被允許執(zhí)行condition抵乓。 一種你有可能用到condition的情況是管理正在進(jìn)行的事件池。

  • 使用多線程要考慮性能損耗章鲤。也就是說(shuō)败徊,多線程下同樣的代碼掏缎,要比單線程下同樣的代碼執(zhí)行效率要低眷蜈,這個(gè)很難提升酌儒。
    *Thread-Safe Designs:避免同時(shí)同步:對(duì)于你工作中的新項(xiàng)目忌怎,或者已經(jīng)存在的項(xiàng)目卢鹦,設(shè)計(jì)時(shí)讓你的代碼和數(shù)據(jù)結(jié)構(gòu)盡量避免同步,是最好的解決方式鸥印。如果每一個(gè)操作都有自己的數(shù)據(jù)集,哪也不需要用到lock來(lái)保護(hù)數(shù)據(jù)狂鞋。即便是兩個(gè)tasks用到了同一個(gè)數(shù)據(jù),那也可以看看有沒(méi)有辦法將數(shù)據(jù)進(jìn)行分割构回,或者給每一個(gè)tasks對(duì)應(yīng)的copy對(duì)象纤掸。

  • 小心活鎖或者死鎖:最好的避免活鎖或者死鎖的方法就是在一個(gè)時(shí)間只使用一個(gè)lock浑塞。如果你需要在同一時(shí)間用到多于一種鎖酌壕,那確保其它threads不要在這個(gè)時(shí)間內(nèi)做類似的事情。

  • 正確的使用volatile變量:如果你已經(jīng)用到了mutex來(lái)保護(hù)一段代碼果港,不要想當(dāng)然的認(rèn)為你需要使用volatile關(guān)鍵字來(lái)保護(hù)重要的變量辛掠。Volatile變量強(qiáng)制每次從內(nèi)存讀取而非寄存器讀取萝衩,這兩個(gè)一起使用會(huì)導(dǎo)致性能出現(xiàn)問(wèn)題猩谊。* 如果mutex自己就足夠保護(hù)變量牌捷,則不要用volatile關(guān)鍵字暗甥。當(dāng)然,也不要為了避免使用mutex就去使用volatile鸿市。一般來(lái)說(shuō),使用mutex或者其它同步機(jī)制比使用volatile變量要好得多剥懒。Volatile關(guān)鍵字只能保證變量從memory中讀取初橘,而不是通過(guò)寄存器讀取

  • 使用Atomic Operations: 雖然Locks是一種在線程中同步的有效方法保檐,使用lock也是很消耗資源的操作夜只,即便是在無(wú)競(jìng)爭(zhēng)的case中蒜魄。相比較谈为,很多atomic operation使用碎片時(shí)間來(lái)完成工作伞鲫,所以可以作為有效率的lock榔昔。 * Atomic operation允許你執(zhí)行簡(jiǎn)單的數(shù)學(xué)操作和邏輯運(yùn)算,在32-bit值或者64bit值上嘹朗。例如Add屹培、Increment怔檩、Decrement媒吗、Logical AND等等闸英。

  • 使用NSLock類:tryLock方法會(huì)嘗試獲取lock,但是如果lock不可得出吹,不會(huì)block状防巍;取而代之的是竹勉,方法會(huì)返回一個(gè)NO次乓。lockBeforeDate方法會(huì)在特定時(shí)間內(nèi)獲取鎖,如果成功返回YES孽水,否則unlock并返回NO票腰。

  • 使用@synchronized關(guān)鍵字:@synchronized關(guān)鍵字做了其它mutex lock做的事:防止不同的線程在同一時(shí)間訪問(wèn)同一個(gè)資源。通過(guò)傳給@synchronized表達(dá)式一個(gè)id女气,它就可以區(qū)分保護(hù)的block杏慰。

  • 其它Cocoa Locks:

    • NSRecursiveLock對(duì)象: RecursiveLock對(duì)象定義了一個(gè)可以被同一個(gè)線程使用多次的lock,而且不會(huì)導(dǎo)致死鎖炼鞠。顧名思義缘滥,這種鎖通常用來(lái)在遞歸方法里防止遞歸不會(huì)鎖住線程時(shí)使用。
    • NSConditionLock對(duì)象:NSConditoinLock對(duì)象定義了一個(gè)mutex lock谒主,只在value值為制定值時(shí)lock和unlock朝扼。 一般來(lái)說(shuō)擎颖,你在使用NSConditionLock時(shí)都是當(dāng)threads需要在特定的順序執(zhí)行,比如一個(gè)線程生產(chǎn)一個(gè)線程消費(fèi)。所以消費(fèi)者只在值為想要的值時(shí)鎖定住生產(chǎn)者荤崇。
    • NSDistributedLock對(duì)象:可以被用在多個(gè)app在多個(gè)hosts上每篷,為了限制對(duì)于同一個(gè)共享資源的訪問(wèn)舱权,比如file文件。 NSDistribultedLock不遵循NSLocking協(xié)議,因此沒(méi)有l(wèi)ock方法。NSDistributedLock提供了tryLock方法讓你決定是否繼續(xù)進(jìn)行羡亩。因?yàn)槔^承自文件系統(tǒng)及志,NSDistributedLock對(duì)象不會(huì)釋放迫卢,除非owner自己釋放每界。如果你的app crash了,之前恰好hold一個(gè)distributedLock,那其它客戶端可能就無(wú)法訪問(wèn)保護(hù)的資源了。這時(shí)候疏虫,你可以使用breakLock方法去break已經(jīng)存在的lock官扣。
  • 可變變量VS不可變變量:

    • 不可變量一般來(lái)說(shuō)是線程安全的焊唬,一旦你創(chuàng)建了他們,你可以從線程獲取或者傳給線程這些變量。
    • 可變對(duì)象一般來(lái)說(shuō)是線程不安全的。
    • 即使一個(gè)方法聲稱要返回一個(gè)不可變的變量,你不能單純的以為變量就是不可變的。如果想要確保變量是不可變的,最好進(jìn)行一步immutable copy操作。
  • Class初始化:OC runtime系統(tǒng)會(huì)發(fā)送initialize消息給每一個(gè)class對(duì)象,這個(gè)過(guò)程遭遇class接收其它消息乖仇。這個(gè)方法建立了runtime 環(huán)境警儒,在它被正式使用之前。在多線程app里,runtime 確保只有一個(gè)線程執(zhí)行initialize方法,這個(gè)線程就是哪個(gè)發(fā)送給class initilaze方法的那個(gè)線程。

  • RunLoops:每一個(gè)線程有且自由一個(gè)run loop。如果你的app是基于Application Kit的,那么主run loop會(huì)自動(dòng)運(yùn)行夫嗓。但是非主線程(和foundation-only app)必須自己執(zhí)行run loop.

  • NSView使用限制(Mac下窍株,和UIView是對(duì)應(yīng)的):

    • 你應(yīng)當(dāng)創(chuàng)建冒滩、銷毀、改變大小、移動(dòng)并且執(zhí)行其他操作時(shí)寻咒,務(wù)必保證NSView對(duì)象在主線程之上限煞。
    • 如果非主線程上的ap想要讓view的部分內(nèi)容在主線程上redraw健霹,不應(yīng)該使用像display、setNeedsDisplay:垒棋,setNeedsDisplayInRect:或者是setViewsNeedDisplay等方法乍构。相反,應(yīng)該發(fā)消息給主線程或者通過(guò)performSelectorOnMainThread:withObject:waitUntilDown:方法來(lái)完成
  • 錯(cuò)誤的使用graphics states會(huì)導(dǎo)致繪畫的效率低于在主線程上繪畫的效率扔茅。

  • NSGraphicsContext使用限制:如果你在非主線程做任何drawing萤晴,一個(gè)NSGraphicsContext實(shí)例會(huì)被創(chuàng)建殖演,而且是特別為那個(gè)線程量身制作座硕。如果在非主線程做任何drawing诸尽,需要手動(dòng)的清理你的drawing調(diào)用。Cocoa不會(huì)在非主線程上自動(dòng)更新view的內(nèi)容,所以你需要調(diào)用flushGraphics方法(NSGraphicsContext)當(dāng)你完成drawing粪薛。如果你的app只在主線程draw內(nèi)容搏恤,那么不需要你調(diào)用flush俏扩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捌木,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坤学,更是在濱河造成了極大的恐慌,老刑警劉巖虚汛,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛋辈,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡将谊,警方通過(guò)查閱死者的電腦和手機(jī)冷溶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)尊浓,“玉大人逞频,你說(shuō)我怎么就攤上這事《俺荩” “怎么了苗胀?”我有些...
    開(kāi)封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)瓦堵。 經(jīng)常有香客問(wèn)我基协,道長(zhǎng),這世上最難降的妖魔是什么菇用? 我笑而不...
    開(kāi)封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任澜驮,我火速辦了婚禮,結(jié)果婚禮上惋鸥,老公的妹妹穿的比我還像新娘杂穷。我一直安慰自己鹅龄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布亭畜。 她就那樣靜靜地躺著扮休,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拴鸵。 梳的紋絲不亂的頭發(fā)上玷坠,一...
    開(kāi)封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音劲藐,去河邊找鬼八堡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛聘芜,可吹牛的內(nèi)容都是我干的兄渺。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼汰现,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼挂谍!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起瞎饲,我...
    開(kāi)封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤口叙,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后嗅战,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妄田,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年驮捍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了疟呐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡东且,死狀恐怖启具,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情苇倡,我是刑警寧澤富纸,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布囤踩,位于F島的核電站旨椒,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏堵漱。R本人自食惡果不足惜综慎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望勤庐。 院中可真熱鬧示惊,春花似錦好港、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至录择,卻和暖如春拔莱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背隘竭。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工塘秦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人动看。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓尊剔,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親菱皆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子须误,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

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