synchronized詳解

synchronized關(guān)鍵字最主要的三種使用方式的總結(jié)

  • 修飾實(shí)例方法,作用于當(dāng)前對(duì)象實(shí)例加鎖近忙,進(jìn)入同步代碼前要獲得當(dāng)前對(duì)象實(shí)例的鎖
  • 修飾靜態(tài)方法,作用于當(dāng)前類對(duì)象加鎖脂崔,進(jìn)入同步代碼前要獲得當(dāng)前類對(duì)象的鎖 锈玉。也就是給當(dāng)前類加鎖爪飘,會(huì)作用于類的所有對(duì)象實(shí)例,因?yàn)殪o態(tài)成員不屬于任何一個(gè)實(shí)例對(duì)象拉背,是類成員( static 表明這是該類的一個(gè)靜態(tài)資源师崎,不管new了多少個(gè)對(duì)象,只有一份椅棺,所以對(duì)該類的所有對(duì)象都加了鎖)犁罩。所以如果一個(gè)線程A調(diào)用一個(gè)實(shí)例對(duì)象的非靜態(tài) synchronized 方法,而線程B需要調(diào)用這個(gè)實(shí)例對(duì)象所屬類的靜態(tài) synchronized 方法两疚,是允許的床估,不會(huì)發(fā)生互斥現(xiàn)象,因?yàn)樵L問(wèn)靜態(tài) synchronized 方法占用的鎖是當(dāng)前類的鎖诱渤,而訪問(wèn)非靜態(tài) synchronized 方法占用的鎖是當(dāng)前實(shí)例對(duì)象鎖丐巫。
  • 修飾代碼塊,指定加鎖對(duì)象源哩,對(duì)給定對(duì)象加鎖鞋吉,進(jìn)入同步代碼庫(kù)前要獲得給定對(duì)象的鎖。 和 synchronized 方法一樣励烦,synchronized(this)代碼塊也是鎖定當(dāng)前對(duì)象的谓着。synchronized 關(guān)鍵字加到 static 靜態(tài)方法和 synchronized(class)代碼塊上都是是給 Class 類上鎖。這里再提一下:synchronized關(guān)鍵字加到非 static 靜態(tài)方法上是給對(duì)象實(shí)例上鎖坛掠。另外需要注意的是:盡量不要使用 synchronized(String a) 因?yàn)镴VM中赊锚,字符串常量池具有緩沖功能!

下面我已一個(gè)常見(jiàn)的面試題為例講解一下 synchronized 關(guān)鍵字的具體使用屉栓。

面試中面試官經(jīng)常會(huì)說(shuō):“單例模式了解嗎舷蒲?來(lái)給我手寫一下!給我解釋一下雙重檢驗(yàn)鎖方式實(shí)現(xiàn)單例模式的原理唄友多!”

雙重校驗(yàn)鎖實(shí)現(xiàn)對(duì)象單例(線程安全)

public class Singleton {

    private volatile static Singleton uniqueInstance;

    private Singleton() {
    }

    public static Singleton getUniqueInstance() {
       //先判斷對(duì)象是否已經(jīng)實(shí)例過(guò)牲平,沒(méi)有實(shí)例化過(guò)才進(jìn)入加鎖代碼
        if (uniqueInstance == null) {
            //類對(duì)象加鎖
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}

另外,需要注意 uniqueInstance 采用 volatile 關(guān)鍵字修飾也是很有必要域滥。

uniqueInstance 采用 volatile 關(guān)鍵字修飾也是很有必要的纵柿, uniqueInstance = new Singleton(); 這段代碼其實(shí)是分為三步執(zhí)行:

  1. 為 uniqueInstance 分配內(nèi)存空間
  2. 初始化 uniqueInstance
  3. 將 uniqueInstance 指向分配的內(nèi)存地址

但是由于 JVM 具有指令重排的特性,執(zhí)行順序有可能變成 1->3->2启绰。指令重排在單線程環(huán)境下不會(huì)出現(xiàn)問(wèn)題昂儒,但是在多線程環(huán)境下會(huì)導(dǎo)致一個(gè)線程獲得還沒(méi)有初始化的實(shí)例。例如委可,線程 T1 執(zhí)行了 1 和 3渊跋,此時(shí) T2 調(diào)用 getUniqueInstance() 后發(fā)現(xiàn) uniqueInstance 不為空,因此返回 uniqueInstance,但此時(shí) uniqueInstance 還未被初始化拾酝。

使用 volatile 可以禁止 JVM 的指令重排燕少,保證在多線程環(huán)境下也能正常運(yùn)行。

synchronized 關(guān)鍵字底層原理總結(jié)

synchronized 關(guān)鍵字底層原理屬于 JVM 層面微宝。

① synchronized 同步語(yǔ)句塊的情況

public class SynchronizedDemo {
    public void method() {
        synchronized (this) {
            System.out.println("synchronized 代碼塊");
        }
    }
}

通過(guò) JDK 自帶的 javap 命令查看 SynchronizedDemo 類的相關(guān)字節(jié)碼信息:首先切換到類的對(duì)應(yīng)目錄執(zhí)行 javac SynchronizedDemo.java 命令生成編譯后的 .class 文件棺亭,然后執(zhí)行javap -c -s -v -l SynchronizedDemo.class

從上面我們可以看出:

synchronized 同步語(yǔ)句塊的實(shí)現(xiàn)使用的是 monitorenter 和 monitorexit 指令蟋软,其中 monitorenter 指令指向同步代碼塊的開(kāi)始位置镶摘,monitorexit 指令則指明同步代碼塊的結(jié)束位置。 當(dāng)執(zhí)行 monitorenter 指令時(shí)岳守,線程試圖獲取鎖也就是獲取 monitor(monitor對(duì)象存在于每個(gè)Java對(duì)象的對(duì)象頭中凄敢,synchronized 鎖便是通過(guò)這種方式獲取鎖的,也是為什么Java中任意對(duì)象可以作為鎖的原因) 的持有權(quán).當(dāng)計(jì)數(shù)器為0則可以成功獲取湿痢,獲取后將鎖計(jì)數(shù)器設(shè)為1也就是加1涝缝。相應(yīng)的在執(zhí)行 monitorexit 指令后,將鎖計(jì)數(shù)器設(shè)為0譬重,表明鎖被釋放拒逮。如果獲取對(duì)象鎖失敗,那當(dāng)前線程就要阻塞等待臀规,直到鎖被另外一個(gè)線程釋放為止滩援。

② synchronized 修飾方法的的情況

public class SynchronizedDemo2 {
    public synchronized void method() {
        System.out.println("synchronized 方法");
    }
}

synchronized 修飾的方法并沒(méi)有 monitorenter 指令和 monitorexit 指令,取得代之的確實(shí)是 ACC_SYNCHRONIZED 標(biāo)識(shí)塔嬉,該標(biāo)識(shí)指明了該方法是一個(gè)同步方法玩徊,JVM 通過(guò)該 ACC_SYNCHRONIZED 訪問(wèn)標(biāo)志來(lái)辨別一個(gè)方法是否聲明為同步方法,從而執(zhí)行相應(yīng)的同步調(diào)用谨究。

在 Java 早期版本中恩袱,synchronized 屬于重量級(jí)鎖,效率低下胶哲,因?yàn)楸O(jiān)視器鎖(monitor)是依賴于底層的操作系統(tǒng)的 Mutex Lock 來(lái)實(shí)現(xiàn)的畔塔,Java 的線程是映射到操作系統(tǒng)的原生線程之上的。如果要掛起或者喚醒一個(gè)線程鸯屿,都需要操作系統(tǒng)幫忙完成俩檬,而操作系統(tǒng)實(shí)現(xiàn)線程之間的切換時(shí)需要從用戶態(tài)轉(zhuǎn)換到內(nèi)核態(tài),這個(gè)狀態(tài)之間的轉(zhuǎn)換需要相對(duì)比較長(zhǎng)的時(shí)間碾盟,時(shí)間成本相對(duì)較高,這也是為什么早期的 synchronized 效率低的原因技竟。慶幸的是在 Java 6 之后 Java 官方對(duì)從 JVM 層面對(duì)synchronized 較大優(yōu)化冰肴,所以現(xiàn)在的 synchronized 鎖效率也優(yōu)化得很不錯(cuò)了。JDK1.6對(duì)鎖的實(shí)現(xiàn)引入了大量的優(yōu)化,如自旋鎖熙尉、適應(yīng)性自旋鎖联逻、鎖消除、鎖粗化检痰、偏向鎖包归、輕量級(jí)鎖等技術(shù)來(lái)減少鎖操作的開(kāi)銷。

JDK1.6 之后的底層優(yōu)化

JDK1.6 對(duì)鎖的實(shí)現(xiàn)引入了大量的優(yōu)化铅歼,如偏向鎖公壤、輕量級(jí)鎖、自旋鎖椎椰、適應(yīng)性自旋鎖厦幅、鎖消除、鎖粗化等技術(shù)來(lái)減少鎖操作的開(kāi)銷慨飘。

鎖主要存在四中狀態(tài)确憨,依次是:無(wú)鎖狀態(tài)、偏向鎖狀態(tài)瓤的、輕量級(jí)鎖狀態(tài)休弃、重量級(jí)鎖狀態(tài),他們會(huì)隨著競(jìng)爭(zhēng)的激烈而逐漸升級(jí)圈膏。注意鎖可以升級(jí)不可降級(jí)塔猾,這種策略是為了提高獲得鎖和釋放鎖的效率。

①偏向鎖

引入偏向鎖的目的和引入輕量級(jí)鎖的目的很像本辐,他們都是為了沒(méi)有多線程競(jìng)爭(zhēng)的前提下桥帆,減少傳統(tǒng)的重量級(jí)鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能消耗。但是不同是:輕量級(jí)鎖在無(wú)競(jìng)爭(zhēng)的情況下使用 CAS 操作去代替使用互斥量慎皱。而偏向鎖在無(wú)競(jìng)爭(zhēng)的情況下會(huì)把整個(gè)同步都消除掉老虫。

偏向鎖的“偏”就是偏心的偏,它的意思是會(huì)偏向于第一個(gè)獲得它的線程茫多,如果在接下來(lái)的執(zhí)行中祈匙,該鎖沒(méi)有被其他線程獲取,那么持有偏向鎖的線程就不需要進(jìn)行同步天揖!關(guān)于偏向鎖的原理可以查看《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐》第二版的13章第三節(jié)鎖優(yōu)化夺欲。

但是對(duì)于鎖競(jìng)爭(zhēng)比較激烈的場(chǎng)合,偏向鎖就失效了今膊,因?yàn)檫@樣場(chǎng)合極有可能每次申請(qǐng)鎖的線程都是不相同的些阅,因此這種場(chǎng)合下不應(yīng)該使用偏向鎖,否則會(huì)得不償失斑唬,需要注意的是市埋,偏向鎖失敗后黎泣,并不會(huì)立即膨脹為重量級(jí)鎖,而是先升級(jí)為輕量級(jí)鎖缤谎。

② 輕量級(jí)鎖

倘若偏向鎖失敗抒倚,虛擬機(jī)并不會(huì)立即升級(jí)為重量級(jí)鎖,它還會(huì)嘗試使用一種稱為輕量級(jí)鎖的優(yōu)化手段(1.6之后加入的)坷澡。輕量級(jí)鎖不是為了代替重量級(jí)鎖托呕,它的本意是在沒(méi)有多線程競(jìng)爭(zhēng)的前提下,減少傳統(tǒng)的重量級(jí)鎖使用操作系統(tǒng)互斥量產(chǎn)生的性能消耗频敛,因?yàn)槭褂幂p量級(jí)鎖時(shí)项郊,不需要申請(qǐng)互斥量。另外姻政,輕量級(jí)鎖的加鎖和解鎖都用到了CAS操作呆抑。 關(guān)于輕量級(jí)鎖的加鎖和解鎖的原理可以查看《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐》第二版的13章第三節(jié)鎖優(yōu)化。

輕量級(jí)鎖能夠提升程序同步性能的依據(jù)是“對(duì)于絕大部分鎖汁展,在整個(gè)同步周期內(nèi)都是不存在競(jìng)爭(zhēng)的”鹊碍,這是一個(gè)經(jīng)驗(yàn)數(shù)據(jù)。如果沒(méi)有競(jìng)爭(zhēng)食绿,輕量級(jí)鎖使用 CAS 操作避免了使用互斥操作的開(kāi)銷侈咕。但如果存在鎖競(jìng)爭(zhēng),除了互斥量開(kāi)銷外器紧,還會(huì)額外發(fā)生CAS操作耀销,因此在有鎖競(jìng)爭(zhēng)的情況下,輕量級(jí)鎖比傳統(tǒng)的重量級(jí)鎖更慢铲汪!如果鎖競(jìng)爭(zhēng)激烈熊尉,那么輕量級(jí)將很快膨脹為重量級(jí)鎖!

③ 自旋鎖和自適應(yīng)自旋

輕量級(jí)鎖失敗后掌腰,虛擬機(jī)為了避免線程真實(shí)地在操作系統(tǒng)層面掛起狰住,還會(huì)進(jìn)行一項(xiàng)稱為自旋鎖的優(yōu)化手段。

互斥同步對(duì)性能最大的影響就是阻塞的實(shí)現(xiàn)齿梁,因?yàn)閽炱鹁€程/恢復(fù)線程的操作都需要轉(zhuǎn)入內(nèi)核態(tài)中完成(用戶態(tài)轉(zhuǎn)換到內(nèi)核態(tài)會(huì)耗費(fèi)時(shí)間)催植。

一般線程持有鎖的時(shí)間都不是太長(zhǎng),所以僅僅為了這一點(diǎn)時(shí)間去掛起線程/恢復(fù)線程是得不償失的勺择。 所以创南,虛擬機(jī)的開(kāi)發(fā)團(tuán)隊(duì)就這樣去考慮:“我們能不能讓后面來(lái)的請(qǐng)求獲取鎖的線程等待一會(huì)而不被掛起呢?看看持有鎖的線程是否很快就會(huì)釋放鎖”省核。為了讓一個(gè)線程等待稿辙,我們只需要讓線程執(zhí)行一個(gè)忙循環(huán)(自旋),這項(xiàng)技術(shù)就叫做自旋气忠。

百度百科對(duì)自旋鎖的解釋:

何謂自旋鎖邻储?它是為實(shí)現(xiàn)保護(hù)共享資源而提出一種鎖機(jī)制未桥。其實(shí),自旋鎖與互斥鎖比較類似芥备,它們都是為了解決對(duì)某項(xiàng)資源的互斥使用。無(wú)論是互斥鎖舌菜,還是自旋鎖萌壳,在任何時(shí)刻,最多只能有一個(gè)保持者日月,也就說(shuō)袱瓮,在任何時(shí)刻最多只能有一個(gè)執(zhí)行單元獲得鎖。但是兩者在調(diào)度機(jī)制上略有不同爱咬。對(duì)于互斥鎖尺借,如果資源已經(jīng)被占用,資源申請(qǐng)者只能進(jìn)入睡眠狀態(tài)精拟。但是自旋鎖不會(huì)引起調(diào)用者睡眠燎斩,如果自旋鎖已經(jīng)被別的執(zhí)行單元保持,調(diào)用者就一直循環(huán)在那里看是否該自旋鎖的保持者已經(jīng)釋放了鎖蜂绎,"自旋"一詞就是因此而得名栅表。

自旋鎖在 JDK1.6 之前其實(shí)就已經(jīng)引入了,不過(guò)是默認(rèn)關(guān)閉的师枣,需要通過(guò)--XX:+UseSpinning參數(shù)來(lái)開(kāi)啟怪瓶。JDK1.6及1.6之后,就改為默認(rèn)開(kāi)啟的了践美。需要注意的是:自旋等待不能完全替代阻塞洗贰,因?yàn)樗€是要占用處理器時(shí)間。如果鎖被占用的時(shí)間短陨倡,那么效果當(dāng)然就很好了敛滋!反之,相反玫膀!自旋等待的時(shí)間必須要有限度矛缨。如果自旋超過(guò)了限定次數(shù)任然沒(méi)有獲得鎖,就應(yīng)該掛起線程帖旨。自旋次數(shù)的默認(rèn)值是10次箕昭,用戶可以修改--XX:PreBlockSpin來(lái)更改

另外,在 JDK1.6 中引入了自適應(yīng)的自旋鎖解阅。自適應(yīng)的自旋鎖帶來(lái)的改進(jìn)就是:自旋的時(shí)間不在固定了落竹,而是和前一次同一個(gè)鎖上的自旋時(shí)間以及鎖的擁有者的狀態(tài)來(lái)決定,虛擬機(jī)變得越來(lái)越“聰明”了货抄。

④ 鎖消除

鎖消除理解起來(lái)很簡(jiǎn)單述召,它指的就是虛擬機(jī)即使編譯器在運(yùn)行時(shí)朱转,如果檢測(cè)到那些共享數(shù)據(jù)不可能存在競(jìng)爭(zhēng),那么就執(zhí)行鎖消除积暖。鎖消除可以節(jié)省毫無(wú)意義的請(qǐng)求鎖的時(shí)間藤为。

⑤ 鎖粗化

原則上,我們?cè)诰帉懘a的時(shí)候夺刑,總是推薦將同步塊的作用范圍限制得盡量小缅疟,——直在共享數(shù)據(jù)的實(shí)際作用域才進(jìn)行同步,這樣是為了使得需要同步的操作數(shù)量盡可能變小遍愿,如果存在鎖競(jìng)爭(zhēng)存淫,那等待線程也能盡快拿到鎖。

大部分情況下沼填,上面的原則都是沒(méi)有問(wèn)題的桅咆,但是如果一系列的連續(xù)操作都對(duì)同一個(gè)對(duì)象反復(fù)加鎖和解鎖,那么會(huì)帶來(lái)很多不必要的性能消耗坞笙。

Synchronized 和 ReenTrantLock 的對(duì)比

① 兩者都是可重入鎖

兩者都是可重入鎖岩饼。“可重入鎖”概念是:自己可以再次獲取自己的內(nèi)部鎖羞海。比如一個(gè)線程獲得了某個(gè)對(duì)象的鎖忌愚,此時(shí)這個(gè)對(duì)象鎖還沒(méi)有釋放,當(dāng)其再次想要獲取這個(gè)對(duì)象的鎖的時(shí)候還是可以獲取的却邓,如果不可鎖重入的話硕糊,就會(huì)造成死鎖。同一個(gè)線程每次獲取鎖腊徙,鎖的計(jì)數(shù)器都自增1简十,所以要等到鎖的計(jì)數(shù)器下降為0時(shí)才能釋放鎖。

② synchronized 依賴于 JVM 而 ReenTrantLock 依賴于 API

synchronized 是依賴于 JVM 實(shí)現(xiàn)的撬腾,前面我們也講到了 虛擬機(jī)團(tuán)隊(duì)在 JDK1.6 為 synchronized 關(guān)鍵字進(jìn)行了很多優(yōu)化螟蝙,但是這些優(yōu)化都是在虛擬機(jī)層面實(shí)現(xiàn)的,并沒(méi)有直接暴露給我們民傻。ReenTrantLock 是 JDK 層面實(shí)現(xiàn)的(也就是 API 層面胰默,需要 lock() 和 unlock 方法配合 try/finally 語(yǔ)句塊來(lái)完成),所以我們可以通過(guò)查看它的源代碼漓踢,來(lái)看它是如何實(shí)現(xiàn)的牵署。

③ ReenTrantLock 比 synchronized 增加了一些高級(jí)功能

相比synchronized,ReenTrantLock增加了一些高級(jí)功能喧半。主要來(lái)說(shuō)主要有三點(diǎn):①等待可中斷奴迅;②可實(shí)現(xiàn)公平鎖;③可實(shí)現(xiàn)選擇性通知(鎖可以綁定多個(gè)條件)

  • ReenTrantLock提供了一種能夠中斷等待鎖的線程的機(jī)制挺据,通過(guò)lock.lockInterruptibly()來(lái)實(shí)現(xiàn)這個(gè)機(jī)制取具。也就是說(shuō)正在等待的線程可以選擇放棄等待脖隶,改為處理其他事情。
  • ReenTrantLock可以指定是公平鎖還是非公平鎖暇检。而synchronized只能是非公平鎖产阱。所謂的公平鎖就是先等待的線程先獲得鎖。 ReenTrantLock默認(rèn)情況是非公平的块仆,可以通過(guò) ReenTrantLock類的ReentrantLock(boolean fair)構(gòu)造方法來(lái)制定是否是公平的心墅。
  • synchronized關(guān)鍵字與wait()和notify/notifyAll()方法相結(jié)合可以實(shí)現(xiàn)等待/通知機(jī)制,ReentrantLock類當(dāng)然也可以實(shí)現(xiàn)榨乎,但是需要借助于Condition接口與newCondition() 方法。Condition是JDK1.5之后才有的瘫筐,它具有很好的靈活性蜜暑,比如可以實(shí)現(xiàn)多路通知功能也就是在一個(gè)Lock對(duì)象中可以創(chuàng)建多個(gè)Condition實(shí)例(即對(duì)象監(jiān)視器),線程對(duì)象可以注冊(cè)在指定的Condition中策肝,從而可以有選擇性的進(jìn)行線程通知肛捍,在調(diào)度線程上更加靈活。 在使用notify/notifyAll()方法進(jìn)行通知時(shí)之众,被通知的線程是由 JVM 選擇的拙毫,用ReentrantLock類結(jié)合Condition實(shí)例可以實(shí)現(xiàn)“選擇性通知” ,這個(gè)功能非常重要棺禾,而且是Condition接口默認(rèn)提供的缀蹄。而synchronized關(guān)鍵字就相當(dāng)于整個(gè)Lock對(duì)象中只有一個(gè)Condition實(shí)例,所有的線程都注冊(cè)在它一個(gè)身上膘婶。如果執(zhí)行notifyAll()方法的話就會(huì)通知所有處于等待狀態(tài)的線程這樣會(huì)造成很大的效率問(wèn)題缺前,而Condition實(shí)例的signalAll()方法 只會(huì)喚醒注冊(cè)在該Condition實(shí)例中的所有等待線程。

如果你想使用上述功能悬襟,那么選擇ReenTrantLock是一個(gè)不錯(cuò)的選擇衅码。

④ 性能已不是選擇標(biāo)準(zhǔn)

在JDK1.6之前,synchronized 的性能是比 ReenTrantLock 差很多脊岳。具體表示為:synchronized 關(guān)鍵字吞吐量隨線程數(shù)的增加逝段,下降得非常嚴(yán)重。而ReenTrantLock 基本保持一個(gè)比較穩(wěn)定的水平割捅。我覺(jué)得這也側(cè)面反映了奶躯, synchronized 關(guān)鍵字還有非常大的優(yōu)化余地。后續(xù)的技術(shù)發(fā)展也證明了這一點(diǎn)棺牧,我們上面也講了在 JDK1.6 之后 JVM 團(tuán)隊(duì)對(duì) synchronized 關(guān)鍵字做了很多優(yōu)化巫糙。JDK1.6 之后,synchronized 和 ReenTrantLock 的性能基本是持平了颊乘。所以網(wǎng)上那些說(shuō)因?yàn)樾阅懿胚x擇 ReenTrantLock 的文章都是錯(cuò)的参淹!JDK1.6之后醉锄,性能已經(jīng)不是選擇synchronized和ReenTrantLock的影響因素了!而且虛擬機(jī)在未來(lái)的性能改進(jìn)中會(huì)更偏向于原生的synchronized浙值,所以還是提倡在synchronized能滿足你的需求的情況下恳不,優(yōu)先考慮使用synchronized關(guān)鍵字來(lái)進(jìn)行同步!優(yōu)化后的synchronized和ReenTrantLock一樣开呐,在很多地方都是用到了CAS操作烟勋。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市筐付,隨后出現(xiàn)的幾起案子卵惦,更是在濱河造成了極大的恐慌,老刑警劉巖瓦戚,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沮尿,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡较解,警方通過(guò)查閱死者的電腦和手機(jī)畜疾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)印衔,“玉大人啡捶,你說(shuō)我怎么就攤上這事〖楸海” “怎么了瞎暑?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)与帆。 經(jīng)常有香客問(wèn)我金顿,道長(zhǎng),這世上最難降的妖魔是什么鲤桥? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任揍拆,我火速辦了婚禮,結(jié)果婚禮上茶凳,老公的妹妹穿的比我還像新娘嫂拴。我一直安慰自己,他們只是感情好贮喧,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布筒狠。 她就那樣靜靜地躺著,像睡著了一般箱沦。 火紅的嫁衣襯著肌膚如雪辩恼。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音灶伊,去河邊找鬼疆前。 笑死,一個(gè)胖子當(dāng)著我的面吹牛聘萨,可吹牛的內(nèi)容都是我干的竹椒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼米辐,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼胸完!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起翘贮,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赊窥,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后狸页,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體誓琼,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年肴捉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叔收。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡齿穗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出饺律,到底是詐尸還是另有隱情窃页,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布复濒,位于F島的核電站脖卖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏巧颈。R本人自食惡果不足惜畦木,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望砸泛。 院中可真熱鬧十籍,春花似錦、人聲如沸唇礁。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)盏筐。三九已至围俘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背界牡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工簿寂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人欢揖。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓陶耍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親她混。 傳聞我的和親對(duì)象是個(gè)殘疾皇子烈钞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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