要點(diǎn)提煉| 理解JVM之內(nèi)存模型&線程

本篇將介紹虛擬機(jī)如何實(shí)現(xiàn)多線程魂那、多線程之間由于共享和競(jìng)爭(zhēng)數(shù)據(jù)而導(dǎo)致的一系列問(wèn)題及解決方案烟瞧。

  • 概述
  • Java內(nèi)存模型
  • Java與線程

1.概述

a.多任務(wù)處理的必要性:

  • 充分利用計(jì)算機(jī)處理器的能力地粪,避免處理器在磁盤(pán)I/O、網(wǎng)絡(luò)通信或數(shù)據(jù)庫(kù)訪問(wèn)時(shí)總是處于等待其他資源的狀態(tài)新啼。
  • 便于一個(gè)服務(wù)端同時(shí)對(duì)多個(gè)客戶(hù)端提供服務(wù)渣磷。通過(guò)指標(biāo)TPS(Transactions Per Second)可衡量一個(gè)服務(wù)性能的高低好壞,它表示每秒服務(wù)端平均能響應(yīng)的請(qǐng)求總數(shù)罢猪,進(jìn)而體現(xiàn)出程序的并發(fā)能力近她。

b.硬件的效率與一致性

為了更好的理解Java內(nèi)存模型,先理解物理計(jì)算機(jī)中的并發(fā)問(wèn)題膳帕,兩者有很高的可比性粘捎。

為了平衡計(jì)算機(jī)的存儲(chǔ)設(shè)備與處理器的運(yùn)算速度之間幾個(gè)數(shù)量級(jí)的差距,引入一層高速緩存(Cache)來(lái)作為內(nèi)存與處理器之間的緩沖:

  • 將運(yùn)算需要使用到的數(shù)據(jù)復(fù)制到緩存中危彩,讓運(yùn)算能快速進(jìn)行攒磨;
  • 當(dāng)運(yùn)算結(jié)束后再?gòu)木彺嫱交貎?nèi)存之中,而無(wú)須讓處理器等待緩慢的內(nèi)存讀寫(xiě)汤徽。

但是基于高速緩存的存儲(chǔ)交互在多處理器系統(tǒng)中會(huì)帶來(lái)緩存一致性(Cache Coherence)的問(wèn)題娩缰。這是因?yàn)槊總€(gè)處理器都有自己的高速緩存,而它們又共享同一主內(nèi)存(Main Memory)谒府,當(dāng)多個(gè)處理器的運(yùn)算任務(wù)都涉及同一塊主內(nèi)存區(qū)域時(shí)拼坎,就可能導(dǎo)致各自的緩存數(shù)據(jù)不一致。解決辦法就是需要各個(gè)處理器訪問(wèn)緩存時(shí)都遵循一些協(xié)議完疫,在讀寫(xiě)時(shí)要根據(jù)協(xié)議來(lái)進(jìn)行操作泰鸡。如下圖。

因此壳鹤,這里所說(shuō)的內(nèi)存模型可以理解為:在特定的操作協(xié)議下盛龄,對(duì)特定的內(nèi)存或高速緩存進(jìn)行讀寫(xiě)訪問(wèn)的過(guò)程抽象。


2.Java內(nèi)存模型(Java Memory Model芳誓,JMM)

a.目的:屏蔽掉各種硬件和操作系統(tǒng)的內(nèi)存訪問(wèn)差異余舶,實(shí)現(xiàn)Java程序在各種平臺(tái)下都能達(dá)到一致的內(nèi)存訪問(wèn)效果。

b.方法:通過(guò)定義程序中各個(gè)變量訪問(wèn)規(guī)則锹淌,即在虛擬機(jī)中將變量存儲(chǔ)到內(nèi)存和從內(nèi)存中取出變量這樣的底層細(xì)節(jié)匿值。

注意:這里的變量與Java中說(shuō)的變量不同,而指的是實(shí)例字段葛圃、靜態(tài)字段和構(gòu)成數(shù)組對(duì)象的元素千扔,但不包括局部變量與方法參數(shù)憎妙,因?yàn)楹笳呤蔷€程私有的,不會(huì)被共享曲楚,自然就不會(huì)存在競(jìng)爭(zhēng)問(wèn)題厘唾。

c.結(jié)構(gòu):模型結(jié)構(gòu)如圖,和上張圖進(jìn)行類(lèi)比龙誊。

  • 主內(nèi)存(Main Memory):所有變量的存儲(chǔ)位置抚垃。直接對(duì)應(yīng)于物理硬件的內(nèi)存。

注意:這里的主內(nèi)存趟大、工作內(nèi)存與要點(diǎn)提煉| 理解JVM之內(nèi)存管理說(shuō)的Java內(nèi)存區(qū)域中的Java堆鹤树、棧、方法區(qū)等并不是同一個(gè)層次的內(nèi)存劃分逊朽。

  • 工作內(nèi)存(Working Memory):每條線程還有自己的工作內(nèi)存罕伯,用于保存被該線程使用到的變量的主內(nèi)存副本拷貝。為了獲取更好的運(yùn)行速度叽讳,虛擬機(jī)可能會(huì)讓工作內(nèi)存優(yōu)先存儲(chǔ)于寄存器和高速緩存中追他。

注意

  • 線程對(duì)變量的所有操作都必須在工作內(nèi)存中進(jìn)行,而不能直接讀寫(xiě)主內(nèi)存中的變量岛蚤。
  • 不同的線程之間也無(wú)法直接訪問(wèn)對(duì)方工作內(nèi)存中的變量邑狸,線程間變量值的傳遞必須通過(guò)主內(nèi)存來(lái)完成。
  • 交互協(xié)議:用于規(guī)定一個(gè)變量如何從主內(nèi)存拷貝到工作內(nèi)存涤妒、如何從工作內(nèi)存同步回主內(nèi)存之類(lèi)的實(shí)現(xiàn)細(xì)節(jié)单雾。共有8種操作:
    • ①用于主內(nèi)存變量:
    • 鎖定lock):把變量標(biāo)識(shí)為一條線程獨(dú)占的狀態(tài)。
    • 解鎖unlock):把處于鎖定狀態(tài)的變量釋放出來(lái)她紫。
    • 讀取read):把變量的值從主內(nèi)存?zhèn)鬏數(shù)骄€程的工作內(nèi)存中硅堆,以便隨后的load動(dòng)作使用。
    • 載入load):把read操作從主內(nèi)存中得到的變量值放入工作內(nèi)存的變量副本中贿讹。
    • ②用于工作內(nèi)存變量:
    • 使用use):把工作內(nèi)存中一個(gè)變量的值傳遞給執(zhí)行引擎硬萍。
    • 賦值assign):把從執(zhí)行引擎接收到的值賦給工作內(nèi)存的變量。
    • 存儲(chǔ)store):把工作內(nèi)存中變量的值傳送到主內(nèi)存中围详,以便隨后的write操作使用。
    • 寫(xiě)入write):把store操作從工作內(nèi)存中得到的變量的值放入主內(nèi)存的變量中祖屏。

結(jié)論:注意是順序非連續(xù)

  • 如果要把變量從主內(nèi)存復(fù)制到工作內(nèi)存助赞,那就要順序地執(zhí)行readload
  • 如果要把變量從工作內(nèi)存同步回主內(nèi)存袁勺,就要順序地執(zhí)行storewrite雹食。

d.確保并發(fā)操作安全的原則

①在Java內(nèi)存模型中規(guī)定了執(zhí)行上述8種基本操作時(shí)需要滿(mǎn)足如下規(guī)則:

  • 不允許readloadstorewrite操作之一單獨(dú)出現(xiàn)期丰,即不允許一個(gè)變量從主內(nèi)存讀取了但工作內(nèi)存不接受群叶,或者從工作內(nèi)存發(fā)起回寫(xiě)了但主內(nèi)存不接受的情況出現(xiàn)吃挑。
  • 不允許一個(gè)線程丟棄它的最近的assign操作,即變量在工作內(nèi)存中改變了之后必須把該變化同步回主內(nèi)存街立。
  • 不允許一個(gè)線程無(wú)原因地舶衬,即沒(méi)有發(fā)生過(guò)任何assign操作就把數(shù)據(jù)從線程的工作內(nèi)存同步回主內(nèi)存中。
  • 一個(gè)新的變量只能在主內(nèi)存中“誕生”赎离,不允許在工作內(nèi)存中直接使用一個(gè)未被初始化(loadassign)的變量逛犹,即對(duì)一個(gè)變量實(shí)施usestore操作之前必須先執(zhí)行過(guò)了assignload操作梁剔。
  • 一個(gè)變量在同一個(gè)時(shí)刻只允許一條線程對(duì)其進(jìn)行lock操作虽画,但lock操作可以被同一條線程重復(fù)執(zhí)行多次,多次執(zhí)行lock后荣病,只有執(zhí)行相同次數(shù)的unlock操作码撰,變量才會(huì)被解鎖。
  • 如果對(duì)一個(gè)變量執(zhí)行lock操作个盆,那將會(huì)清空工作內(nèi)存中此變量的值脖岛,在執(zhí)行引擎使用這個(gè)變量前,需要重新執(zhí)行loadassign操作初始化變量的值砾省。
  • 如果一個(gè)變量事先沒(méi)有被lock操作鎖定鸡岗,那就不允許對(duì)它執(zhí)行unlock操作,也不允許去unlock一個(gè)被其他線程鎖定住的變量编兄。
  • 對(duì)一個(gè)變量執(zhí)行unlock操作之前轩性,必須先把此變量同步回主內(nèi)存中。

可見(jiàn)這么多規(guī)則非常繁瑣狠鸳,實(shí)踐也麻煩揣苏,下面再介紹一個(gè)等效判斷原則--先行發(fā)生原則。

先行發(fā)生原則:是Java內(nèi)存模型中定義的兩項(xiàng)操作之間的偏序關(guān)系件舵。下面例舉一些“天然的”先行發(fā)生關(guān)系卸察,無(wú)須任何同步器協(xié)助就已經(jīng)存在,可以在編碼中直接使用铅祸。

  • 程序次序規(guī)則(Program Order Rule):在一個(gè)線程內(nèi)坑质,按照控制流順序,書(shū)寫(xiě)在前面的操作先行發(fā)生于書(shū)寫(xiě)在后面的操作临梗。
  • 管程鎖定規(guī)則(Monitor Lock Rule):一個(gè)unlock操作先行發(fā)生于后面對(duì)同一個(gè)鎖的lock操作涡扼。
  • volatile變量規(guī)則(Volatile Variable Rule):對(duì)一個(gè)volatile變量的寫(xiě)操作先行發(fā)生于后面對(duì)這個(gè)變量的操作。
  • 線程啟動(dòng)規(guī)則(Thread Start Rule):Thread對(duì)象的start()先行發(fā)生于此線程的每一個(gè)動(dòng)作盟庞。
  • 線程終止規(guī)則(Thread Termination Rule):線程中的所有操作都先行發(fā)生于對(duì)此線程的終止檢測(cè).可通過(guò)Thread.join()結(jié)束吃沪、Thread.isAlive()的返回值等手段檢測(cè)到線程已經(jīng)終止執(zhí)行。
  • 線程中斷規(guī)則(Thread Interruption Rule):對(duì)線程interrupt()的調(diào)用先行發(fā)生于被中斷線程的代碼檢測(cè)到中斷事件的發(fā)生什猖∑北耄可通過(guò)Thread.interrupted()檢測(cè)到是否有中斷發(fā)生红淡。
  • 對(duì)象終結(jié)規(guī)則(Finalizer Rule):一個(gè)對(duì)象的初始化完成先行發(fā)生于它的finalize()的開(kāi)始。
  • 傳遞性(Transitivity):如果操作A先行發(fā)生于操作B降铸,操作B先行發(fā)生于操作C在旱,那么操作A一定先行發(fā)生于操作C。

e.Java內(nèi)存模型保證并發(fā)過(guò)程的原子性垮耳、可見(jiàn)性和有序性的措施:

  • 原子性(Atomicity):一個(gè)操作要么都執(zhí)行要么都不執(zhí)行颈渊。
    • 可直接保證的原子性變量操作有:readload终佛、assign俊嗽、usestorewrite铃彰,因此可認(rèn)為基本數(shù)據(jù)類(lèi)型的訪問(wèn)讀寫(xiě)是具備原子性的绍豁。
    • 若需要保證更大范圍的原子性,可通過(guò)更高層次的字節(jié)碼指令monitorentermonitorexit來(lái)隱式地使用lockunlock這兩個(gè)操作牙捉,反映到Java代碼中就是同步代碼塊synchronized關(guān)鍵字竹揍。
  • 可見(jiàn)性(Visibility):當(dāng)一個(gè)線程修改了共享變量的值,其他線程能夠立即得知這個(gè)修改邪铲。
    • 通過(guò)在變量修改后將新值同步回主內(nèi)存芬位,在變量讀取前從主內(nèi)存刷新變量值這種依賴(lài)主內(nèi)存作為傳遞媒介的方式來(lái)實(shí)現(xiàn)。
    • 提供三個(gè)關(guān)鍵字保證可見(jiàn)性:volatile能保證新值能立即同步到主內(nèi)存带到,且每次使用前立即從主內(nèi)存刷新昧碉;synchronized對(duì)一個(gè)變量執(zhí)行unlock操作之前可以先把此變量同步回主內(nèi)存中;被final修飾的字段在構(gòu)造器中一旦初始化完成且構(gòu)造器沒(méi)有把this的引用傳遞出去揽惹,就可以在其他線程中就能看見(jiàn)final字段的值被饿。
  • 有序性(Ordering):程序代碼按照指令順序執(zhí)行。
    • 如果在本線程內(nèi)觀察搪搏,所有的操作都是有序的狭握,指“線程內(nèi)表現(xiàn)為串行的語(yǔ)義”;如果在一個(gè)線程中觀察另一個(gè)線程疯溺,所有的操作都是無(wú)序的论颅,指“指令重排序”現(xiàn)象和“工作內(nèi)存與主內(nèi)存同步延遲”現(xiàn)象。
    • 提供兩個(gè)關(guān)鍵字保證有序性:volatile 本身就包含了禁止指令重排序的語(yǔ)義囱嫩;synchronized保證一個(gè)變量在同一個(gè)時(shí)刻只允許一條線程對(duì)其進(jìn)行l(wèi)ock操作嗅辣,使得持有同一個(gè)鎖的兩個(gè)同步塊只能串行地進(jìn)入。

3.Java與線程

a.線程實(shí)現(xiàn)的三種方式

①使用內(nèi)核線程(Kernel-Level Thread,KLT)

  • 定義:直接由操作系統(tǒng)內(nèi)核支持的線程挠说。
  • 原理:由內(nèi)核來(lái)完成線程切換,內(nèi)核通過(guò)操縱調(diào)度器(Scheduler)對(duì)線程進(jìn)行調(diào)度愿题,并負(fù)責(zé)將線程的任務(wù)映射到各個(gè)處理器上损俭。每個(gè)內(nèi)核線程可以視為內(nèi)核的一個(gè)分身蛙奖, 這樣操作系統(tǒng)就有能力同時(shí)處理多件事情。
  • 多線程內(nèi)核(Multi-Threads Kernel):支持多線程的內(nèi)核
  • 輕量級(jí)進(jìn)程(Light Weight Process,LWP):內(nèi)核線程的一種高級(jí)接口
    • 優(yōu)點(diǎn):每個(gè)輕量級(jí)進(jìn)程都由一個(gè)內(nèi)核線程支持杆兵,因此每個(gè)都成為一個(gè)獨(dú)立的調(diào)度單元雁仲,即使有一個(gè)輕量級(jí)進(jìn)程在系統(tǒng)調(diào)用中阻塞,也不會(huì)影響整個(gè)進(jìn)程繼續(xù)工作琐脏。
    • 缺點(diǎn):由于基于內(nèi)核線程實(shí)現(xiàn)攒砖,所以各種線程操作(創(chuàng)建、析構(gòu)及同步)都需要進(jìn)行系統(tǒng)調(diào)用日裙,代價(jià)相對(duì)較高吹艇,需要在用戶(hù)態(tài)(User Mode)和內(nèi)核態(tài)(Kernel Mode)中來(lái)回切換;另外昂拂,一個(gè)系統(tǒng)支持輕量級(jí)進(jìn)程的數(shù)量是有限的受神。
    • 一對(duì)一線程模型:輕量級(jí)進(jìn)程與內(nèi)核線程之間1:1的關(guān)系,如圖所示

②使用用戶(hù)線程(User Thread,UT)

  • 定義:廣義上認(rèn)為一個(gè)線程不是內(nèi)核線程就是用戶(hù)線程格侯;狹義上認(rèn)為用戶(hù)線程指的是完全建立在用戶(hù)空間的線程庫(kù)上鼻听,而系統(tǒng)內(nèi)核不能感知線程存在的實(shí)現(xiàn)。
  • 優(yōu)點(diǎn):由于用戶(hù)線程的建立联四、同步撑碴、銷(xiāo)毀和調(diào)度完全在用戶(hù)態(tài)中完成,不需要內(nèi)核的幫助朝墩,甚至可以不需要切換到內(nèi)核態(tài)醉拓,所以操作非常快速且低消耗的鱼辙,且可以支持規(guī)模更大的線程數(shù)量廉嚼。
  • 缺點(diǎn):由于沒(méi)有系統(tǒng)內(nèi)核的支援,所有的線程操作都需要用戶(hù)程序自己處理倒戏,線程的創(chuàng)建怠噪、切換和調(diào)度都是需要考慮的問(wèn)題,實(shí)現(xiàn)較復(fù)雜杜跷。
  • 一對(duì)多的線程模型進(jìn)程:進(jìn)程與用戶(hù)線程之間1:N的關(guān)系傍念,如圖所示

③使用用戶(hù)線程加輕量級(jí)進(jìn)程混合

  • 定義:既存在用戶(hù)線程,也存在輕量級(jí)進(jìn)程葛闷。
  • 優(yōu)點(diǎn):用戶(hù)線程完全建立在用戶(hù)空間中憋槐,因此用戶(hù)線程的創(chuàng)建、切換淑趾、析構(gòu)等操作依然廉價(jià)阳仔,并且可以支持大規(guī)模的用戶(hù)線程并發(fā);操作系統(tǒng)提供支持的輕量級(jí)進(jìn)程作為用戶(hù)線程和內(nèi)核線程之間的橋梁扣泊,可以使用內(nèi)核提供的線程調(diào)度功能及處理器映射近范,且用戶(hù)線程的系統(tǒng)調(diào)用要通過(guò)輕量級(jí)線程來(lái)完成嘶摊,大大降低了整個(gè)進(jìn)程被完全阻塞的風(fēng)險(xiǎn)。
  • 多對(duì)多的線程模型:用戶(hù)線程與輕量級(jí)進(jìn)程的數(shù)量比不定评矩,即用戶(hù)線程與輕量級(jí)進(jìn)程之間N:M的關(guān)系叶堆,如圖所示

那么Java線程的實(shí)現(xiàn)是選擇哪一種呢?答案是不確定的斥杜。操作系統(tǒng)支持怎樣的線程模型虱颗,在很大程度上決定了Java虛擬機(jī)的線程是怎樣映射的。線程模型只對(duì)線程的并發(fā)規(guī)模和操作成本產(chǎn)生影響蔗喂,而對(duì)Java程序的編碼和運(yùn)行過(guò)程來(lái)說(shuō)忘渔,這些差異都是透明的。

b.Java線程調(diào)度的兩種方式

線程調(diào)度:指系統(tǒng)為線程分配處理器使用權(quán)的過(guò)程弱恒。

協(xié)同式線程調(diào)度(Cooperative Threads-Scheduling)

  • 線程本身來(lái)控制線程的執(zhí)行時(shí)間辨萍。線程把自己的工作執(zhí)行完后,要主動(dòng)通知系統(tǒng)切換到另外一個(gè)線程上返弹。
  • 好處:實(shí)現(xiàn)簡(jiǎn)單锈玉;切換操作自己可知,不存在線程同步的問(wèn)題义起。
  • 壞處:線程執(zhí)行時(shí)間不可控拉背,假如一個(gè)線程編寫(xiě)有問(wèn)題一直不告知系統(tǒng)進(jìn)行線程切換,那么程序就會(huì)一直被阻塞默终。

搶占式線程調(diào)度(Preemptive Threads-Scheduling)

  • 系統(tǒng)來(lái)分配每個(gè)線程的執(zhí)行時(shí)間椅棺。
  • 好處:線程執(zhí)行時(shí)間是系統(tǒng)可控的,不存在一個(gè)線程導(dǎo)致整個(gè)進(jìn)程阻塞的問(wèn)題齐蔽。
  • 可以通過(guò)設(shè)置線程優(yōu)先級(jí)两疚,優(yōu)先級(jí)越高的線程越容易被系統(tǒng)選擇執(zhí)行。

但是線程優(yōu)先級(jí)并不是太靠譜含滴,一方面因?yàn)镴ava的線程是通過(guò)映射到系統(tǒng)的原生線程上來(lái)實(shí)現(xiàn)的诱渤,所以線程調(diào)度最終還是取決于操作系統(tǒng),在一些平臺(tái)上不同的優(yōu)先級(jí)實(shí)際會(huì)變得相同谈况;另一方面優(yōu)先級(jí)可能會(huì)被系統(tǒng)自行改變勺美。

c.線程的五種狀態(tài)

在任意一個(gè)時(shí)間點(diǎn),一個(gè)線程只能有且只有其中的一種狀態(tài):

  • 新建(New):線程創(chuàng)建后尚未啟動(dòng)
  • 運(yùn)行(Runable):包括正在執(zhí)行(Running)和等待著CPU為它分配執(zhí)行時(shí)間(Ready)兩種
  • 無(wú)限期等待(Waiting):該線程不會(huì)被分配CPU執(zhí)行時(shí)間碑韵,要等待被其他線程顯式地喚醒赡茸。以下方法會(huì)讓線程陷入無(wú)限期等待狀態(tài):
    • 沒(méi)有設(shè)置Timeout參數(shù)的Object.wait()
    • 沒(méi)有設(shè)置Timeout參數(shù)的Thread.join()
    • LockSupport.park()
  • 限期等待(Timed Waiting):該線程不會(huì)被分配CPU執(zhí)行時(shí)間,但在一定時(shí)間后會(huì)被系統(tǒng)自動(dòng)喚醒祝闻。以下方法會(huì)讓線程進(jìn)入限期等待狀態(tài):
    • Thread.sleep()
    • 設(shè)置了Timeout參數(shù)的Object.wai()
    • 設(shè)置了Timeout參數(shù)的Thread.join()
    • LockSupport.parkNanos()
    • LockSupport.parkUntil()
  • 阻塞(Blocked):線程被阻塞

注意區(qū)別

  • 阻塞狀態(tài):在等待獲取到一個(gè)排他鎖占卧,在另外一個(gè)線程放棄這個(gè)鎖的時(shí)候發(fā)生;
  • 等待狀態(tài):在等待一段時(shí)間或者喚醒動(dòng)作的發(fā)生,在程序等待進(jìn)入同步區(qū)域的時(shí)候發(fā)生屉栓。
  • 結(jié)束(Terminated):線程已經(jīng)結(jié)束執(zhí)行

下圖是線程狀態(tài)之間的轉(zhuǎn)換:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末舷蒲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子友多,更是在濱河造成了極大的恐慌,老刑警劉巖堤框,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件域滥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蜈抓,警方通過(guò)查閱死者的電腦和手機(jī)启绰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)沟使,“玉大人委可,你說(shuō)我怎么就攤上這事±拔耍” “怎么了着倾?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)燕少。 經(jīng)常有香客問(wèn)我卡者,道長(zhǎng),這世上最難降的妖魔是什么客们? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任崇决,我火速辦了婚禮,結(jié)果婚禮上底挫,老公的妹妹穿的比我還像新娘恒傻。我一直安慰自己,他們只是感情好建邓,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布盈厘。 她就那樣靜靜地躺著,像睡著了一般涝缝。 火紅的嫁衣襯著肌膚如雪扑庞。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天拒逮,我揣著相機(jī)與錄音罐氨,去河邊找鬼。 笑死滩援,一個(gè)胖子當(dāng)著我的面吹牛栅隐,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼租悄,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谨究!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起泣棋,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤胶哲,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后潭辈,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鸯屿,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年把敢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寄摆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡修赞,死狀恐怖婶恼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情柏副,我是刑警寧澤勾邦,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站搓扯,受9級(jí)特大地震影響检痰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜锨推,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一铅歼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧换可,春花似錦椎椰、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至译荞,卻和暖如春瓤的,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吞歼。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工圈膏, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人篙骡。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓稽坤,卻偏偏與公主長(zhǎng)得像丈甸,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子尿褪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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