synchronized 實(shí)現(xiàn)原理

要了解 synchronized 的原理需要先理清楚兩件事情:對(duì)象頭和 Monitor。在JVM中划栓,對(duì)象是分成三部分存在的:

對(duì)象頭

實(shí)例數(shù)據(jù)

對(duì)其填充

對(duì)象實(shí)例

實(shí)例數(shù)據(jù)和對(duì)其填充與synchronized無(wú)關(guān)

Java對(duì)象在堆內(nèi)存分布

當(dāng)我們?cè)?Java 代碼中淋肾,使用 new 創(chuàng)建一個(gè)對(duì)象的時(shí)候屎勘,JVM 會(huì)在堆中創(chuàng)建一個(gè) instanceOopDesc 對(duì)象赡译,這個(gè)對(duì)象中包含了對(duì)象頭以及實(shí)例數(shù)據(jù)。

instanceOopDesc 的基類為 oopDesc 類濒析。它的結(jié)構(gòu)如下:

2.png

其中 _mark 和 metadata 一起組成了對(duì)象頭正什。metadata 主要保存了類元數(shù)據(jù),不需要做過(guò)多介紹号杏。這里重點(diǎn)看下 _mark 屬性婴氮,_mark 是 markOop 類型數(shù)據(jù),一般稱它為標(biāo)記字段(Mark Word)盾致,其中主要存儲(chǔ)了對(duì)象的 hashCode主经、分代年齡、鎖標(biāo)志位庭惜,是否偏向鎖等罩驻。

實(shí)例數(shù)據(jù)存放類的屬性數(shù)據(jù)信息,包括父類的屬性信息护赊,如果是數(shù)組的實(shí)例部分還包括數(shù)組的長(zhǎng)度惠遏,這部分內(nèi)存按4字節(jié)對(duì)齊;對(duì)其填充不是必須部分骏啰,由于虛擬機(jī)要求對(duì)象起始地址必須是8字節(jié)的整數(shù)倍节吮,對(duì)齊填充僅僅是為了使字節(jié)對(duì)齊。對(duì)象頭是我們需要關(guān)注的重點(diǎn)判耕,它是synchronized實(shí)現(xiàn)鎖的基礎(chǔ)透绩,因?yàn)閟ynchronized申請(qǐng)鎖、上鎖、釋放鎖都與對(duì)象頭有關(guān)帚豪。

對(duì)象頭主要結(jié)構(gòu)是由Mark WordClass Metadata Address 組成碳竟,其中Mark Word存儲(chǔ)對(duì)象的hashCode、鎖信息或分代年齡或GC標(biāo)志等信息狸臣,Class Metadata Address是類型指針指向?qū)ο蟮念愒獢?shù)據(jù)瞭亮,JVM通過(guò)該指針確定該對(duì)象是哪個(gè)類的實(shí)例。

用一張圖來(lái)表示 32 位 Java 虛擬機(jī)的 Mark Word 的默認(rèn)存儲(chǔ)結(jié)構(gòu)如下:

32 位 Java 虛擬機(jī)的 Mark Word 的默認(rèn)存儲(chǔ)結(jié)構(gòu)

鎖也分不同狀態(tài)

JDK6之前只有兩個(gè)狀態(tài):無(wú)鎖固棚、有鎖(重量級(jí)鎖)

而在JDK6之后對(duì)synchronized進(jìn)行了優(yōu)化,新增了兩種狀態(tài)仙蚜,總共就是四個(gè)狀態(tài):

  1. 無(wú)鎖狀態(tài)此洲、
  2. 偏向鎖、
  3. 輕量級(jí)鎖委粉、
  4. 重量級(jí)鎖呜师,
image-20210127204421146

其中無(wú)鎖就是一種狀態(tài)了。鎖的類型和狀態(tài)在對(duì)象頭Mark Word中都有記錄贾节,在申請(qǐng)鎖汁汗、鎖升級(jí)等過(guò)程中JVM都需要讀取對(duì)象的Mark Word數(shù)據(jù)。

? 每一個(gè)鎖都對(duì)應(yīng)一個(gè)monitor對(duì)象栗涂,在HotSpot虛擬機(jī)中它是由ObjectMonitor實(shí)現(xiàn)的(C++實(shí)現(xiàn))知牌。每個(gè)對(duì)象都存在著一個(gè)monitor與之關(guān)聯(lián),對(duì)象與其monitor之間的關(guān)系有存在多種實(shí)現(xiàn)方式斤程,如monitor可以與對(duì)象一起創(chuàng)建銷毀或當(dāng)線程試圖獲取對(duì)象鎖時(shí)自動(dòng)生成角寸,但當(dāng)一個(gè)monitor被某個(gè)線程持有后,它便處于鎖定狀態(tài)忿墅。

ObjectMonitor() {
    _header       = NULL;
    _count        = 0;  //鎖計(jì)數(shù)器
    _waiters      = 0,
    _recursions   = 0;
    _object       = NULL;
    _owner        = NULL;
    _WaitSet      = NULL; //處于wait狀態(tài)的線程扁藕,會(huì)被加入到_WaitSet
    _WaitSetLock  = 0 ;
    _Responsible  = NULL ;
    _succ         = NULL ;
    _cxq          = NULL ;
    FreeNext      = NULL ;
    _EntryList    = NULL ; //處于等待鎖block狀態(tài)的線程,會(huì)被加入到該列表
    _SpinFreq     = 0 ;
    _SpinClock    = 0 ;
    OwnerIsThread = 0 ;
  } 

默認(rèn)情況下疚脐,沒(méi)有線程進(jìn)行加鎖操作亿柑,所以鎖對(duì)象中的 Mark Word 處于無(wú)鎖狀態(tài)。但是考慮到 JVM 的空間效率棍弄,Mark Word 被設(shè)計(jì)成為一個(gè)非固定的數(shù)據(jù)結(jié)構(gòu)望薄,以便存儲(chǔ)更多的有效數(shù)據(jù),它會(huì)根據(jù)對(duì)象本身的狀態(tài)復(fù)用自己的存儲(chǔ)空間照卦,如 32 位 JVM 下式矫,除了上述列出的 Mark Word 默認(rèn)存儲(chǔ)結(jié)構(gòu)外,還有如下可能變化的結(jié)構(gòu):

Mark Word 存儲(chǔ)結(jié)構(gòu)

Monitor

Monitor 可以把它理解為一個(gè)同步工具役耕,也可以描述為一種同步機(jī)制采转。實(shí)際上,它是一個(gè)保存在對(duì)象頭中的一個(gè)對(duì)象。在 markOop 中有如下代碼:

markOop

通過(guò) monitor() 方法創(chuàng)建一個(gè) ObjectMonitor 對(duì)象故慈,而 ObjectMonitor 就是 Java 虛擬機(jī)中的 Monitor 的具體實(shí)現(xiàn)板熊。因此 Java 中每個(gè)對(duì)象都會(huì)有一個(gè)對(duì)應(yīng)的 ObjectMonitor 對(duì)象,這也是 Java 中所有的 Object 都可以作為鎖對(duì)象的原因察绷。

ObjectMonitor 其中有幾個(gè)比較關(guān)鍵的屬性:

ObjectMonitor

當(dāng)多個(gè)線程同時(shí)訪問(wèn)一段同步代碼時(shí)干签,首先會(huì)進(jìn)入 _EntryList 隊(duì)列中,當(dāng)某個(gè)線程通過(guò)競(jìng)爭(zhēng)獲取到對(duì)象的 monitor 后拆撼,monitor 會(huì)把 _owner 變量設(shè)置為當(dāng)前線程容劳,同時(shí) monitor 中的計(jì)數(shù)器 _count 加 1,即獲得對(duì)象鎖闸度。

若持有 monitor 的線程調(diào)用 wait() 方法竭贩,將釋放當(dāng)前持有的 monitor,_owner 變量恢復(fù)為 null莺禁, _count 自減 1留量,同時(shí)該線程進(jìn)入 _WaitSet 集合中等待被喚醒。若當(dāng)前線程執(zhí)行完畢也將釋放 monitor(鎖)并復(fù)位變量的值哟冬,以便其他線程進(jìn)入獲取 monitor(鎖)楼熄。

ObjectMonitor 工作機(jī)制

ObjectMonitor中有兩個(gè)隊(duì)列

**_WaitSet ** 等待鎖的線程集合

_EntryList指孤,進(jìn)入鎖范圍的線程集合

Demo演示

demo

通過(guò) 3 個(gè)線程分別執(zhí)行以下同步代碼塊,鎖對(duì)象是 lock 對(duì)象排监,在 JVM 中會(huì)有一個(gè) ObjectMonitor 對(duì)象與之對(duì)應(yīng)。如下圖所示:

demo-ObjectMonitor-1

分別使用 3 個(gè)線程來(lái)執(zhí)行以上同步代碼塊践樱。默認(rèn)情況下翰灾,3 個(gè)線程都會(huì)先進(jìn)入 ObjectMonitor 中的 EntrySet 隊(duì)列中青柄,如下所示:

demo-ObjectMonitor-2

假設(shè)線程 2 首先通過(guò)競(jìng)爭(zhēng)獲取到了鎖對(duì)象,則 ObjectMonitor 中的 Owner 指向線程 2预侯,并將 count 加 1致开。結(jié)果如下:

demo-ObjectMonitor-3

上圖中 Owner 指向線程 2 表示它已經(jīng)成功獲取到鎖(Monitor)對(duì)象,其他線程只能處于阻塞(blocking)狀態(tài)萎馅。如果線程 2 在執(zhí)行過(guò)程中調(diào)用 wait() 操作双戳,則線程 2 會(huì)釋放鎖(Monitor)對(duì)象,以便其他線程進(jìn)入獲取鎖(Monitor)對(duì)象糜芳,Owner 變量恢復(fù)為 null飒货,count 做減 1 操作,同時(shí)線程 2 會(huì)添加到 WaitSet 集合峭竣,進(jìn)入等待(waiting)狀態(tài)并等待被喚醒塘辅。結(jié)果如下:

demo-ObjectMonitor-4

然后線程 1 和線程 3 再次通過(guò)競(jìng)爭(zhēng)獲取到鎖(Monitor)對(duì)象,則重新將 Owner 指向成功獲取到鎖的線程皆撩。假設(shè)線程 1 獲取到鎖扣墩,如下:
demo-ObjectMonitor-5

如果在線程 1 執(zhí)行過(guò)程中調(diào)用 notify 操作將線程 2 喚醒哲银,則當(dāng)前處于 WaitSet 中的線程 2 會(huì)被重新添加到 EntrySet 集合中,并嘗試重新獲取競(jìng)爭(zhēng)鎖(Monitor)對(duì)象呻惕。但是 notify 操作并不會(huì)是使程 1 釋放鎖(Monitor)對(duì)象荆责。結(jié)果如下

demo-ObjectMonitor-6

當(dāng)線程 1 中的代碼執(zhí)行完畢以后,同樣會(huì)自動(dòng)釋放鎖亚脆,以便其他線程再次獲取鎖對(duì)象做院。

實(shí)際上,ObjectMonitor 的同步機(jī)制是 JVM 對(duì)操作系統(tǒng)級(jí)別的 Mutex Lock(互斥鎖)的管理過(guò)程濒持,其間都會(huì)轉(zhuǎn)入操作系統(tǒng)內(nèi)核態(tài)键耕。也就是說(shuō) synchronized 實(shí)現(xiàn)鎖,在“重量級(jí)鎖”狀態(tài)下柑营,當(dāng)多個(gè)線程之間切換上下文時(shí)郁竟,還是一個(gè)比較重量級(jí)的操作。

JVM對(duì)synchronized的優(yōu)化

從 Java 6 開(kāi)始由境,虛擬機(jī)對(duì) synchronized 關(guān)鍵字做了多方面的優(yōu)化,主要目的就是蓖议,避免 ObjectMonitor 的訪問(wèn)虏杰,減少“重量級(jí)鎖”的使用次數(shù),并最終減少線程上下文切換的頻率 勒虾。其中主要做了以下幾個(gè)優(yōu)化: 鎖自旋纺阔、輕量級(jí)鎖、偏向鎖修然。

上面講到鎖有四種狀態(tài)笛钝,并且會(huì)因?qū)嶋H情況進(jìn)行膨脹升級(jí),其膨脹方向是:無(wú)鎖——>偏向鎖——>輕量級(jí)鎖——>重量級(jí)鎖愕宋,并且膨脹方向不可逆玻靡。

鎖有四種狀態(tài)

鎖自旋

線程的阻塞和喚醒需要 CPU 從用戶態(tài)轉(zhuǎn)為核心態(tài),頻繁的阻塞和喚醒對(duì) CPU 來(lái)說(shuō)是一件負(fù)擔(dān)很重的工作中贝,勢(shì)必會(huì)給系統(tǒng)的并發(fā)性能帶來(lái)很大的壓力囤捻,所以 Java 引入了自旋鎖的操作。實(shí)際上自旋鎖在 Java 1.4 就被引入了邻寿,默認(rèn)關(guān)閉蝎土,但是可以使用參數(shù) -XX:+UseSpinning 將其開(kāi)啟。但是從 Java 6 之后默認(rèn)開(kāi)啟绣否。

所謂自旋誊涯,就是讓該線程等待一段時(shí)間,不會(huì)被立即掛起蒜撮,看當(dāng)前持有鎖的線程是否會(huì)很快釋放鎖暴构。而所謂的等待就是執(zhí)行一段無(wú)意義的循環(huán)即可(自旋)。

自旋鎖也存在一定的缺陷:自旋鎖要占用 CPU,如果鎖競(jìng)爭(zhēng)的時(shí)間比較長(zhǎng)丹壕,那么自旋通常不能獲得鎖庆械,白白浪費(fèi)了自旋占用的 CPU 時(shí)間。這通常發(fā)生在鎖持有時(shí)間長(zhǎng)菌赖,且競(jìng)爭(zhēng)激烈的場(chǎng)景中缭乘,此時(shí)應(yīng)主動(dòng)禁用自旋鎖。

偏向鎖

輕量級(jí)鎖是在沒(méi)有鎖競(jìng)爭(zhēng)情況下的鎖狀態(tài)琉用,但是在有些時(shí)候鎖不僅存在多線程的競(jìng)爭(zhēng)堕绩,而且總是由同一個(gè)線程獲得。因此為了讓線程獲得鎖的代價(jià)更低引入了偏向鎖的概念邑时。偏向鎖的意思是如果一個(gè)線程獲得了一個(gè)偏向鎖奴紧,如果在接下來(lái)的一段時(shí)間中沒(méi)有其他線程來(lái)競(jìng)爭(zhēng)鎖,那么持有偏向鎖的線程再次進(jìn)入或者退出同一個(gè)同步代碼塊晶丘,不需要再次進(jìn)行搶占鎖和釋放鎖的操作黍氮。偏向鎖可以通過(guò) -XX:+UseBiasedLocking 開(kāi)啟或者關(guān)閉。

一句話總結(jié)它的作用:減少同一線程獲取鎖的代價(jià)浅浮。在大多數(shù)情況下沫浆,鎖不存在多線程競(jìng)爭(zhēng),總是由同一線程多次獲得滚秩,那么此時(shí)就是偏向鎖专执。

核心思想:如果一個(gè)線程獲得了鎖,那么鎖就進(jìn)入偏向模式郁油,此時(shí)Mark Word的結(jié)構(gòu)也就變?yōu)槠蜴i結(jié)構(gòu)本股,當(dāng)該線程再次請(qǐng)求鎖時(shí),無(wú)需再做任何同步操作桐腌,即獲取鎖的過(guò)程只需要檢查Mark Word的鎖標(biāo)記位為偏向鎖以及當(dāng)前線程ID等于Mark Word的ThreadID即可拄显,這樣就省去了大量有關(guān)鎖申請(qǐng)的操作。

偏向鎖的具體實(shí)現(xiàn)就是在鎖對(duì)象的對(duì)象頭中有個(gè) ThreadId 字段案站,默認(rèn)情況下這個(gè)字段是空的凿叠,當(dāng)?shù)谝淮潍@取鎖的時(shí)候,就將自身的 ThreadId 寫(xiě)入鎖對(duì)象的 Mark Word 中的 ThreadId 字段內(nèi)嚼吞,將是否偏向鎖的狀態(tài)置為 01盒件。這樣下次獲取鎖的時(shí)候,直接檢查 ThreadId 是否和自身線程 Id 一致舱禽,如果一致炒刁,則認(rèn)為當(dāng)前線程已經(jīng)獲取了鎖,因此不需再次獲取鎖誊稚,略過(guò)了輕量級(jí)鎖和重量級(jí)鎖的加鎖階段翔始。提高了效率罗心。

過(guò)程: 先說(shuō)無(wú)鎖—>偏向鎖。鎖的標(biāo)志位都為01城瞎。
當(dāng)一個(gè)線程訪問(wèn)同步塊并獲取鎖時(shí)渤闷,會(huì)在對(duì)象頭和棧幀中的鎖記錄里存儲(chǔ)鎖偏向的線程ID,以后該線程在進(jìn)入和退出同步塊時(shí)不需要花費(fèi)CAS操作來(lái)加鎖和解鎖脖镀,而只需簡(jiǎn)單的測(cè)試一下對(duì)象頭的Mark Word里是否存儲(chǔ)著指向當(dāng)前線程的偏向鎖飒箭,如果測(cè)試成功,表示線程已經(jīng)獲得了鎖蜒灰,如果測(cè)試失敗弦蹂,則需要再測(cè)試下Mark Word中偏向鎖的標(biāo)識(shí)是否設(shè)置成1(表示當(dāng)前是偏向鎖),如果沒(méi)有設(shè)置强窖,則使用CAS競(jìng)爭(zhēng)鎖凸椿,如果設(shè)置了,則嘗試使用CAS將對(duì)象頭的偏向鎖指向當(dāng)前線程翅溺。

? 要注意的是脑漫,偏向鎖使用了一種等到競(jìng)爭(zhēng)出現(xiàn)才釋放鎖的機(jī)制,所以當(dāng)其他線程嘗試競(jìng)爭(zhēng)偏向鎖時(shí)咙崎,持有偏向鎖的線程才會(huì)釋放鎖优幸。偏向鎖的撤銷,需要等待全局安全點(diǎn)(在這個(gè)時(shí)間點(diǎn)上沒(méi)有字節(jié)碼正在執(zhí)行)叙凡,它會(huì)首先暫停擁有偏向鎖的線程,然后檢查持有偏向鎖的線程是否活著密末,如果線程不處于活動(dòng)狀態(tài)握爷,則將對(duì)象頭設(shè)置成無(wú)鎖狀態(tài),如果線程仍然活著严里,擁有偏向鎖的棧會(huì)被執(zhí)行新啼,遍歷偏向?qū)ο蟮逆i記錄,棧中的鎖記錄和對(duì)象頭的Mark Word要么重新偏向于其他線程刹碾,要么恢復(fù)到無(wú)鎖或者標(biāo)記對(duì)象不適合作為偏向鎖燥撞,最后喚醒暫停的線程。

輕量級(jí)鎖

輕量級(jí)鎖是由偏向鎖升級(jí)而來(lái)迷帜,當(dāng)存在第二個(gè)線程申請(qǐng)同一個(gè)鎖對(duì)象時(shí)物舒,偏向鎖就會(huì)立即升級(jí)為輕量級(jí)鎖。注意這里的第二個(gè)線程只是申請(qǐng)鎖戏锹,不存在兩個(gè)線程同時(shí)競(jìng)爭(zhēng)鎖冠胯,可以是一前一后地交替執(zhí)行同步塊。

有時(shí)候 Java 虛擬機(jī)中會(huì)存在這種情形:對(duì)于一塊同步代碼锦针,雖然有多個(gè)不同線程會(huì)去執(zhí)行荠察,但是這些線程是在不同的時(shí)間段交替請(qǐng)求這把鎖對(duì)象置蜀,也就是不存在鎖競(jìng)爭(zhēng)的情況。在這種情況下悉盆,鎖會(huì)保持在輕量級(jí)鎖的狀態(tài)盯荤,從而避免重量級(jí)鎖的阻塞和喚醒操作。

要了解輕量級(jí)鎖的工作流程焕盟,還是需要再次看下對(duì)象頭中的 Mark Word秋秤。上文中已經(jīng)提到,鎖的標(biāo)志位包含幾種情況:00 代表輕量級(jí)鎖京髓、01 代表無(wú)鎖(或者偏向鎖)航缀、10 代表重量級(jí)鎖、11 則跟垃圾回收算法的標(biāo)記有關(guān)堰怨。

當(dāng)線程執(zhí)行某同步代碼時(shí)芥玉,Java 虛擬機(jī)會(huì)在當(dāng)前線程的棧幀中開(kāi)辟一塊空間(Lock Record)作為該鎖的記錄,如下圖所示:

17.png

然后 Java 虛擬機(jī)會(huì)嘗試使用 CAS(Compare And Swap)操作备图,將鎖對(duì)象的 Mark Word 拷貝到這塊空間中灿巧,并且將鎖記錄中的 owner 指向 Mark Word。結(jié)果如下:
18.png

當(dāng)線程再次執(zhí)行此同步代碼塊時(shí)揽涮,判斷當(dāng)前對(duì)象的 Mark Word 是否指向當(dāng)前線程的棧幀抠藕,如果是則表示當(dāng)前線程已經(jīng)持有當(dāng)前對(duì)象的鎖,則直接執(zhí)行同步代碼塊蒋困;否則只能說(shuō)明該鎖對(duì)象已經(jīng)被其他線程搶占了盾似,這時(shí)輕量級(jí)鎖需要膨脹為重量級(jí)鎖。

重量級(jí)鎖

重量級(jí)鎖是由輕量級(jí)鎖升級(jí)而來(lái)雪标,當(dāng)同一時(shí)間有多個(gè)線程競(jìng)爭(zhēng)鎖時(shí)零院,鎖就會(huì)被升級(jí)成重量級(jí)鎖,此時(shí)其申請(qǐng)鎖帶來(lái)的開(kāi)銷也就變大村刨。

重量級(jí)鎖一般使用場(chǎng)景會(huì)在追求吞吐量告抄,同步塊或者同步方法執(zhí)行時(shí)間較長(zhǎng)的場(chǎng)景。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末嵌牺,一起剝皮案震驚了整個(gè)濱河市打洼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌逆粹,老刑警劉巖募疮,帶你破解...
    沈念sama閱讀 222,946評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異僻弹,居然都是意外死亡酝锅,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門奢方,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)搔扁,“玉大人爸舒,你說(shuō)我怎么就攤上這事「宥祝” “怎么了扭勉?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,716評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)苛聘。 經(jīng)常有香客問(wèn)我涂炎,道長(zhǎng),這世上最難降的妖魔是什么设哗? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,222評(píng)論 1 300
  • 正文 為了忘掉前任唱捣,我火速辦了婚禮,結(jié)果婚禮上网梢,老公的妹妹穿的比我還像新娘震缭。我一直安慰自己,他們只是感情好战虏,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,223評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布拣宰。 她就那樣靜靜地躺著,像睡著了一般烦感。 火紅的嫁衣襯著肌膚如雪巡社。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,807評(píng)論 1 314
  • 那天手趣,我揣著相機(jī)與錄音晌该,去河邊找鬼。 笑死绿渣,一個(gè)胖子當(dāng)著我的面吹牛朝群,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怯晕,決...
    沈念sama閱讀 41,235評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼潜圃,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缸棵!你這毒婦竟也來(lái)了舟茶?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,189評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤堵第,失蹤者是張志新(化名)和其女友劉穎吧凉,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體踏志,經(jīng)...
    沈念sama閱讀 46,712評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡阀捅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,775評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了针余。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饲鄙。...
    茶點(diǎn)故事閱讀 40,926評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凄诞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忍级,到底是詐尸還是另有隱情帆谍,我是刑警寧澤,帶...
    沈念sama閱讀 36,580評(píng)論 5 351
  • 正文 年R本政府宣布轴咱,位于F島的核電站汛蝙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏朴肺。R本人自食惡果不足惜窖剑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,259評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望戈稿。 院中可真熱鬧西土,春花似錦、人聲如沸器瘪。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,750評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)橡疼。三九已至援所,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間欣除,已是汗流浹背住拭。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,867評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留历帚,地道東北人滔岳。 一個(gè)月前我還...
    沈念sama閱讀 49,368評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像挽牢,于是被迫代替她去往敵國(guó)和親谱煤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,930評(píng)論 2 361

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