2018-10-27并發(fā)問題-java內(nèi)存模型

pdf下載:
https://pan.baidu.com/s/1SM__fev_esbYhVOWo90RKw

深入理解Java內(nèi)存模型(一)——基礎(chǔ)

深入理解Java內(nèi)存模型(二)——重排序

深入理解Java內(nèi)存模型(三)——順序一致性

深入理解Java內(nèi)存模型(四)——volatile

深入理解Java內(nèi)存模型(五)——鎖

深入理解Java內(nèi)存模型(六)——final

深入理解Java內(nèi)存模型(七)——總結(jié)

防丟失: 深入理解java內(nèi)存模型系列文章

java內(nèi)存模型

解決內(nèi)存可見行問題。

并發(fā)編程處理兩個問題:
1.線程之間如何通信
2.線程之間如何同步

通信:線程之間以何種機制來交換信息;

線程之間的通信機制有兩種:
1.共享內(nèi)存
2.消息傳遞

共享內(nèi)存:
線程之間共享程序的公共狀態(tài)酸役,線程之間通過寫-讀內(nèi)存中公共狀態(tài)來隱式進行通信

消息傳遞:
線程之間沒有公共狀態(tài),線程之間必須通過明確的發(fā)送消息顯示進行通信

同步:程序用于控制不同線程之間操作執(zhí)行相對順序的機制蛹稍;

在共享內(nèi)存并發(fā)模型里愿伴,同步是顯式進行的趟咆;
程序員必須顯式指定某個方法或某段代碼需要在線程之間互斥執(zhí)行园蝠。

在消息傳遞模型的并發(fā)編程里渺蒿,由于消息的發(fā)送必須在消息的接收之前,因此同步是隱式進行的砰琢;

java的并發(fā)采用的是共享內(nèi)存模型蘸嘶,java線程之間的通信總是隱式進行的良瞧。整個通信過程對程序員完全透明陪汽。

如果編寫多線程的java程序員不理解隱式進行的線程之間通信的工作機制训唱,很可能會遇到各種奇怪的內(nèi)存可見性問題。

關(guān)鍵詞:內(nèi)存可見行

java內(nèi)存模型的抽象

共享變量:實例域挚冤,靜態(tài)域况增,數(shù)組元素

不會在線程共享:
局部變量,方法定義參數(shù)训挡,異常處理器對象:
不會有內(nèi)存可見行性問題澳骤,也不受內(nèi)存模型影響。

jmm決定一個線程對共享變量寫入何時對另一個線程可見澜薄。

共享主內(nèi)存
線程私有內(nèi)存

jmm通過控制主內(nèi)存與每個線程的本地內(nèi)存之間的交互为肮,來為java程序員提供內(nèi)存可見行保證。

重排序

編譯器和處理器對指令重排序肤京。

重排序分為三種:
編譯器重排序

指令級并行的重排序

內(nèi)存系統(tǒng)的重排序

這些重排序都可以導(dǎo)致多線程出現(xiàn)內(nèi)存可見性問題颊艳。

禁止重排序:jmm有重排序規(guī)則。處理器級別的有內(nèi)存屏障

jmm(java內(nèi)存模型)
是屬于語言級的內(nèi)存模型忘分,它確保在不同的編譯器和不同的處理器平臺之上棋枕,通過禁止特定類型的編譯器重排序和處理器重排序,為程序員提供一致的內(nèi)存可見行保證妒峦。

處理器重排序與內(nèi)存屏障指令

從內(nèi)存操作實際發(fā)生的順序來看重斑,直到處理器A執(zhí)行A3來刷新自己的寫緩存區(qū),寫操作A1才算真正執(zhí)行了肯骇。雖然處理器A執(zhí)行內(nèi)存操作的順序為:A1->A2窥浪,但內(nèi)存操作實際發(fā)生的順序卻是:A2->A1。此時笛丙,處理器A的內(nèi)存操作順序被重排序了(處理器B的情況和處理器A一樣寒矿,這里就不贅述了)。
這句話怎么理解若债?
對于處理器A來說符相,
a=1;//A1
x=b;//A2

是可以先執(zhí)行A2再執(zhí)行A1的,因為先執(zhí)行A2再執(zhí)行A1蠢琳,對程序沒有任何影響啊终;a=1;和x=b;之間并沒有邏輯上的先后因果關(guān)系。不存在數(shù)據(jù)依賴

寫緩存僅對自己的處理器可見傲须,它會導(dǎo)致處理器執(zhí)行內(nèi)存操作的順序可能會與內(nèi)存實際的操作執(zhí)行順序不一致蓝牲。

x86僅僅允許對寫-讀操作做重排序。因為使用了寫緩沖區(qū)泰讽。

為了保證內(nèi)存可見性,java編譯器會在生成指令序列的適當位置插入內(nèi)存屏障來禁止特定類型的處理器重排序例衍。

happens-before:用來闡述操作之間的內(nèi)存可見行

從jdk5開始昔期,java使用新的內(nèi)存模型(jsr-133內(nèi)存模型)
jsr-133使用hanppens-before的概念來闡述操作之間的內(nèi)存可見行。

jmm中佛玄,如果一個操作執(zhí)行的結(jié)果需要對另一操作可見硼一,那么這兩個操作之間必須要存在happens-before關(guān)系。

這里提到的兩個操作梦抢,可以在一個線程之內(nèi)般贼,也可以在多個線程之間。

happens-before規(guī)則:
程序順序規(guī)則:
一個線程內(nèi)的所有操作奥吩,happens-before于該線程中的任意后續(xù)操作哼蛆。

互斥鎖規(guī)則:
對一個互斥鎖的釋放/解鎖,happens-before于隨后對這個互斥鎖的獲取/加鎖霞赫。

volatile變量規(guī)則:
對一個volatile域的寫腮介,happens-before 于任意后續(xù)對這個volatile域的讀。

傳遞性:
如果A happens-before B,且B happens-before C端衰, 那么 A happens-before C

也就就說可以通過加鎖叠洗,volatile修飾變量保證內(nèi)存可見性

注意:兩個操作之間具有happens-before關(guān)系靴迫,并不意味著前一個操作必須要在后一個操作之前執(zhí)行惕味!

happens-before僅僅要求前一個操作(執(zhí)行的結(jié)果)對后一個操作可見

被volatile修飾的變量玉锌,在讀之前名挥,要先等待寫并刷新的主內(nèi)存,

互斥鎖主守,在獲取鎖之間禀倔,必須等待鎖的釋放;

一個線程內(nèi)参淫,代碼按順序執(zhí)行救湖。

重排序

如果兩個操作訪問同一個變量,且這兩個操作中有一個寫操作涎才,此時兩個操作之間就存在了數(shù)據(jù)依賴性鞋既。

數(shù)據(jù)依賴性分下列三種類型:
寫后讀
寫后寫
讀后寫

上面三種情況,只要重排序兩個操作的執(zhí)行順序耍铜,程序的執(zhí)行結(jié)果將會被改變邑闺。

前面提到過,編譯器和處理器可能會對操作做重排序棕兼。編譯器和處理器在重排序時陡舅,會遵守數(shù)據(jù)依賴性,編譯器和處理器不會改變存在數(shù)據(jù)依賴關(guān)系的兩個操作的執(zhí)行順序伴挚。

注意靶衍,這里所說的數(shù)據(jù)依賴性僅針對單個處理器中執(zhí)行的指令序列和單個線程中執(zhí)行的操作灾炭,不同處理器之間和不同線程之間的數(shù)據(jù)依賴性不被編譯器和處理器考慮。

as-if-serial語義

不管怎么重排序(編譯器和處理器為了提高并發(fā)度)颅眶,(單線程)程序的執(zhí)行結(jié)果不能被改變蜈出。編譯器,runtime,和處理器都必須遵循as-if-serial語義帚呼。

為了遵循as-if-serial語義掏缎,編譯器和處理器不會對存在數(shù)據(jù)依賴關(guān)系的操作做重排序皱蹦。因為這種重排序會改變執(zhí)行結(jié)果煤杀。

但是,如果操作之間不存在數(shù)據(jù)依賴關(guān)系沪哺,這些操作被編譯器和處理器重排序沈自。

double pi = 3.14;//A
double r = 1.0;//B
double area = pirr;//C

A和C之間存在數(shù)據(jù)依賴關(guān)系,同時B和C之間也存在數(shù)據(jù)依賴關(guān)系辜妓。因此在最終執(zhí)行的指令序列中枯途,C不能被重排序到A和B的前面(C排到A和B的前面,程序的結(jié)果將會被改變)籍滴。
但A和B之間沒有數(shù)據(jù)依賴關(guān)系酪夷,編譯器和處理器可以重排序A和B之間的執(zhí)行順序。

實際上:執(zhí)行順序也可能是
double r = 1.0;//B
double pi = 3.14;//A
double area = pirr;//C

as-if-serial語義把單線程程序保護了起來孽惰,遵守as-if-serial語義的編譯器晚岭,runtime 和處理器共同為編寫單線程程序的程序員創(chuàng)建了一個幻覺:單線程程序是按程序的順序來執(zhí)行的。as-if-serial語義使單線程程序員無需擔心重排序會干擾他們勋功,也無需擔心內(nèi)存可見性問題坦报。

程序順序規(guī)則

在計算機中,軟件技術(shù)和硬件技術(shù)有一個共同的目標:在不改變程序執(zhí)行結(jié)果的前提下狂鞋,盡可能的開發(fā)并行度片择。
編譯器和處理器遵從這一目標,從happens- before的定義我們可以看出骚揍,JMM同樣遵從這一目標字管。

重排序?qū)Χ嗑€程的影響

控制依賴關(guān)系

當代碼中存在控制依賴性時,會影響指令序列執(zhí)行的并行度信不。
為此嘲叔,編譯器和處理器會采用猜測(Speculation)執(zhí)行來克服控制相關(guān)性對并行度的影響

在單線程程序中浑塞,對存在控制依賴的操作重排序借跪,不會改變執(zhí)行結(jié)果(這也是as-if-serial語義允許對存在控制依賴的操作做重排序的原因);但在多線程程序中酌壕,對存在控制依賴的操作重排序掏愁,可能會改變程序的執(zhí)行結(jié)果歇由。

數(shù)據(jù)競爭與順序一致性保證

當程序未正確同步時,就會存在數(shù)據(jù)競爭果港。java內(nèi)存模型規(guī)范對數(shù)據(jù)競爭的定義如下:

在一個線程中寫一個變量沦泌,
在另一個線程讀同一個變量,
而且寫和讀沒有通過同步來排序辛掠。

jmm對正確同步的多線程程序的內(nèi)存一致性做了如下保證:
如果程序是正確同步的谢谦,程序的執(zhí)行將具有順序一致性--即程序的執(zhí)行結(jié)果與該程序在順序一致性內(nèi)存模型中的執(zhí)行結(jié)果相同,
這里的同步是指廣義上的同步萝衩,包括對常用同步原語(lock,volatile和final)的正確使用回挽。

順序一致性內(nèi)存模型

順序一致性內(nèi)存模型是一個被計算機科學(xué)家理想化了的理論參考模型,
它為程序員提供了極強的內(nèi)存可見性保證猩谊。

順序一致性內(nèi)存模型有兩大特性:
一個線程中所有操作必須按照程序的順序來執(zhí)行千劈。

(不管程序是否同步)所有線程都只能看到一個單一的操作執(zhí)行順序。
在順序一致性內(nèi)存模型中牌捷,每個操作都必須原子執(zhí)行且立即對所有線程可見墙牌。

舉例說明:
順序一致性保證
未同步程序在順序一致性模型中雖然整體執(zhí)行順序是無序的,但所有線程都只能看到一個一致的整體執(zhí)行順序暗甥。以上圖為例喜滨,線程A和B看到的執(zhí)行順序都是:B1->A1->A2->B2->A3->B3。之所以能得到這個保證是因為順序一致性內(nèi)存模型中的每個操作必須立即對任意線程可見撤防。

但是虽风,jmm中就沒有這個保證。未同步程序在jmm中不但整體的執(zhí)行順序是無序的即碗,而且所有線程看到的操作順序也可能不一致焰情。
比如,在當前線程把寫過的數(shù)據(jù)緩存在本地內(nèi)存中剥懒,且還沒有刷新到主內(nèi)存之前内舟,這個寫操作僅對當前線程可見;從其他線程的角度來觀察初橘,會認為這個寫操作根本還沒有被當前線程執(zhí)行验游。只有當前線程把本地內(nèi)存中寫過的數(shù)據(jù)刷新到主內(nèi)存之后,這個寫操作才能對其他線程可見保檐。在這種情況下耕蝉,當前線程和其它線程看到的操作執(zhí)行順序?qū)⒉灰恢隆?/p>

同步程序順序一致性效果

在順序一致性模型中,所有操作完全按程序的順序串行執(zhí)行夜只。而在JMM中垒在,臨界區(qū)內(nèi)的代碼可以重排序(但JMM不允許臨界區(qū)內(nèi)的代碼“逸出”到臨界區(qū)之外,那樣會破壞監(jiān)視器的語義)扔亥。JMM會在退出監(jiān)視器和進入監(jiān)視器這兩個關(guān)鍵時間點做一些特別處理场躯,使得線程在這兩個時間點具有與順序一致性模型相同的內(nèi)存視圖(具體細節(jié)后文會說明)谈为。雖然線程A在臨界區(qū)內(nèi)做了重排序,但由于監(jiān)視器的互斥執(zhí)行的特性踢关,這里的線程B根本無法“觀察”到線程A在臨界區(qū)內(nèi)的重排序伞鲫。這種重排序既提高了執(zhí)行效率,又沒有改變程序的執(zhí)行結(jié)果签舞。

從這里我們可以看到JMM在具體實現(xiàn)上的基本方針:在不改變(正確同步的)程序執(zhí)行結(jié)果的前提下秕脓,盡可能的為編譯器和處理器的優(yōu)化打開方便之門。

未同步程序的執(zhí)行特性

JMM不保證未同步程序的執(zhí)行結(jié)果與該程序在順序一致性模型中的執(zhí)行結(jié)果一致儒搭。因為未同步程序在順序一致性模型中執(zhí)行時吠架,整體上是無序的,其執(zhí)行結(jié)果無法預(yù)知师妙。保證未同步程序在兩個模型中的執(zhí)行結(jié)果一致毫無意義诵肛。

和順序一致性模型一樣屹培,未同步程序在JMM中的執(zhí)行時默穴,整體上也是無序的,其執(zhí)行結(jié)果也無法預(yù)知褪秀。同時蓄诽,未同步程序在這兩個模型中的執(zhí)行特性有下面幾個差異:

順序一致性模型保證單線程內(nèi)的操作會按程序的順序執(zhí)行,而JMM不保證單線程內(nèi)的操作會按程序的順序執(zhí)行(比如上面正確同步的多線程程序在臨界區(qū)內(nèi)的重排序)媒吗。這一點前面已經(jīng)講過了仑氛,這里就不再贅述。
順序一致性模型保證所有線程只能看到一致的操作執(zhí)行順序闸英,而JMM不保證所有線程能看到一致的操作執(zhí)行順序锯岖。這一點前面也已經(jīng)講過,這里就不再贅述甫何。
JMM不保證對64位的long型和double型變量的讀/寫操作具有原子性出吹,而順序一致性模型保證對所有的內(nèi)存讀/寫操作都具有原子性。

線程之間的通信由java內(nèi)存模型jmm控制辙喂,jmm決定一個線程對共享變量的寫入何時對另一個線程可見捶牢。從抽象的角度來看,jmm定義了線程和主內(nèi)存之間的抽象關(guān)系:線程之間的共享變量存儲在主內(nèi)存中巍耗,每個線程都有一個私有的本地內(nèi)存(local memory )秋麸,本地內(nèi)存中存儲了該線程以讀/寫共享變量的副本。本地內(nèi)存是jmm中一個抽象概念炬太,并不真實存在。它涵蓋了緩存亲族,寫緩存區(qū)吓歇,寄存器以及其他的硬件和編譯器優(yōu)化票腰,

volatile的特性

理解volatile特性的一個好方法是:把對volatile變量的單個讀/寫,看作是使用同一個monitor對這個單個讀/寫操作做了同步杏慰。

class VolatileFeaturesExample {
    volatile long vl = 0L;  //使用volatile聲明64位的long型變量

    public void set(long l) {
        vl = l;   //單個volatile變量的寫
    }

    public void getAndIncrement () {
        vl++;    //復(fù)合(多個)volatile變量的讀/寫
    }


    public long get() {
        return vl;   //單個volatile變量的讀
    }
}

假設(shè)有多個線程分別調(diào)用上面程序的三個方法,這個程序在語意上和下面程序等價:

class VolatileFeaturesExample {
    long vl = 0L;               // 64位的long型普通變量

    public synchronized void set(long l) {     //對單個的普通 變量的寫用同一個監(jiān)視器同步
        vl = l;
    }

    public void getAndIncrement () { //普通方法調(diào)用
        long temp = get();           //調(diào)用已同步的讀方法
        temp += 1L;                  //普通寫操作
        set(temp);                   //調(diào)用已同步的寫方法
    }
    public synchronized long get() { 
    //對單個的普通變量的讀用同一個監(jiān)視器同步
        return vl;
    }
}

監(jiān)視器鎖的happens-before規(guī)則保證釋放監(jiān)視器和獲取監(jiān)視器的兩個線程之間的內(nèi)存可見性轰胁,這意味著對一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量最后的寫入赃阀。

監(jiān)視器鎖的語義決定了臨界區(qū)代碼的執(zhí)行具有原子性。這意味著即使是64位的long型和double型變量榛斯,只要它是volatile變量,對該變量的讀寫就將具有原子性搂捧。如果是多個volatile操作或類似于volatile++這種復(fù)合操作驮俗,這些操作整體上不具有原子性。

簡而言之允跑,volatile變量自身具有下列特性:
可見行王凑。對一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量最后的寫入聋丝。

原子性:對任意單個volatile變量的讀/寫具有原子性索烹。但類似于volatile++這種復(fù)合操作不具有原子性。

鎖的釋放--獲取建立的happens-before關(guān)系

鎖是java并發(fā)編程中最重要的同步機制弱睦。

鎖除了讓臨界區(qū)互斥執(zhí)行外百姓,還可以讓釋放鎖的線程向獲取同一個鎖的線程發(fā)送消息。

鎖內(nèi)存語義的具體實現(xiàn)機制

final

對于final域每篷,編譯器和處理器要遵守兩個重排序規(guī)則:

1.在構(gòu)造函數(shù)內(nèi)對一個final域的寫入瓣戚,與隨后把這個 被構(gòu)造對象的引用(這個對象 指的是這個構(gòu)造方法所在的類) 賦值給一個引用變量,這兩個操作之間不能重排序焦读。

2.初次讀一個包含final域的對象的引用子库,與隨后初次讀這個final域,這兩個操作之間不能重排序矗晃。

寫final域的重排序規(guī)則

寫final域的重排序規(guī)則禁止把final域的寫重排序到構(gòu)造函數(shù)之外仑嗅。這個規(guī)則的實現(xiàn)包含下面2個方面:

JMM禁止編譯器把final域的寫重排序到構(gòu)造函數(shù)之外。

編譯器會在final域的寫之后,構(gòu)造函數(shù)return之前仓技,插入一個StoreStore屏障鸵贬。這個屏障禁止處理器把final域的寫重排序到構(gòu)造函數(shù)之外。

寫final域的重排序規(guī)則可以確保:在對象引用為任意線程可見之前脖捻,對象的final域已經(jīng)被正確初始化過了阔逼,而普通域不具有這個保障。

這里final域為一個引用類型地沮,它引用一個int型的數(shù)組對象嗜浮。對于引用類型,寫final域的重排序規(guī)則對編譯器和處理器增加了如下約束:

在構(gòu)造函數(shù)內(nèi)對一個final引用的對象的成員域的寫入摩疑,與隨后在構(gòu)造函數(shù)外把這個被構(gòu)造對象的引用賦值給一個引用變量危融,這兩個操作之間不能重排序。

處理器內(nèi)存模型

順序一致性內(nèi)存模型是一個理論參考模型雷袋,jmm處理器內(nèi)存模型
在設(shè)計時通常會把順序一致性內(nèi)存模型作為參照吉殃。

jmm和處理器內(nèi)存模型在設(shè)計時通常會把順序一致性內(nèi)存模型作為參照,
jmm和處理器內(nèi)存模型在設(shè)計時會對順序一致性模型做一些放松楷怒,因為如果完全按照順序一致性模型來處理處理器和jmm,那么很多的處理器和編譯器優(yōu)化都要被禁止迫卢,這對執(zhí)行性能將會有很多的影響。

根據(jù)對不同類型讀/寫操作組合的執(zhí)行順序的放松每界,可以把常見處理器內(nèi)存模型劃分為下面幾種類型:

注意眨层,這里處理器對讀/寫操作的放松馒闷,是以兩個操作之間不存在數(shù)據(jù)依賴性為前提的(因為處理器要遵守as-if-serial語義處理器不會對存在數(shù)據(jù)依賴性的兩個內(nèi)存操作做重排序)捺疼。

jmm卧秘,處理器內(nèi)存模型與順序一致性內(nèi)存模型之間的關(guān)系

jmm是個語言級的內(nèi)存模型羞福,
處理器內(nèi)存模型是個硬件級的內(nèi)存模型坯临,
順序一致內(nèi)存模型是個理論參考模型看靠。

因此挟炬,JMM把happens- before要求禁止的重排序分為了下面兩類:

會改變程序執(zhí)行結(jié)果的重排序谤祖。

不會改變程序執(zhí)行結(jié)果的重排序老速。

JMM對這兩種不同性質(zhì)的重排序,采取了不同的策略:

對于會改變程序執(zhí)行結(jié)果的重排序额湘,JMM要求編譯器和處理器必須禁止這種重排序锋华。

對于不會改變程序執(zhí)行結(jié)果的重排序箭窜,JMM對編譯器和處理器不作要求(JMM允許這種重排序)磺樱。

jmm的內(nèi)存可見性保證

1.單線程程序竹捉。單線程程序不會出現(xiàn)內(nèi)存可見行問題。
編譯器物遇,runtime和處理器會共同確保單線程程序的執(zhí)行結(jié)果與該程序在順序一致性模型中的執(zhí)行結(jié)果相同。

2.正確同步的多線程程序乃沙。
正確同步的多線程程序的執(zhí)行將具有順序一致性警儒。
(程序的執(zhí)行結(jié)果與該程序在順序一致性模型中的執(zhí)行結(jié)果相同)
這是jmm關(guān)注的重點眶根,jmm通過限制編譯器和處理器的重排序來為程序員提供內(nèi)存可見性的保證属百。

3.未同步/未正確同步的多線程程序

jmm為它們提供了最小安全性保障:
線程執(zhí)行時讀取到的值族扰,要么是之前某個線程寫入的值,要么是默認值(0,null,false)怒竿。

jsr-133對舊內(nèi)存模型的修補

增強volatile的內(nèi)存語義耕驰。

增強final的內(nèi)存語義朦肘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厚骗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子夫嗓,更是在濱河造成了極大的恐慌舍咖,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窍株,死亡現(xiàn)場離奇詭異后裸,居然都是意外死亡,警方通過查閱死者的電腦和手機微驶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篇恒,“玉大人,你說我怎么就攤上這事款筑〈茁玻” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵饭寺,是天一觀的道長限煞。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么糖埋? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮兆解,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己具练,他們只是感情好,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般松蒜。 火紅的嫁衣襯著肌膚如雪运褪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天屯断,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛灭忠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播机隙,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起咸产,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤屑彻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后搏恤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體搞莺,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡绍刮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年嫉戚,在試婚紗的時候發(fā)現(xiàn)自己被綠了帆啃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡深浮,死狀恐怖菌瘫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情栖忠,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布蛋辈,位于F島的核電站,受9級特大地震影響渐白,放射性物質(zhì)發(fā)生泄漏逞频。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望基协。 院中可真熱鬧,春花似錦澜驮、人聲如沸杂穷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拴鸵。三九已至劲藐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留脚曾,地道東北人鲁冯。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拔莱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

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