并發(fā)編程(五):深入理解synchronized

Java對(duì)象頭(64位虛擬機(jī))

  • 整個(gè)對(duì)象頭一共有128位,Mark Word有64位近刘,Klass Word有64位宣脉,但是Klass Word因?yàn)橹羔槈嚎s的原因被壓縮為32位,使用對(duì)象頭一共有96位瓷患,而且現(xiàn)在我們更需要關(guān)注的是前64位。至于Klass Word指向了方法區(qū)的模板類遣妥,字節(jié)碼擅编。
  • 對(duì)象頭還不是一成不變的,就表格可以看出箫踩,對(duì)象的狀態(tài)會(huì)改變對(duì)象頭的數(shù)值爱态,這里我們分為5個(gè)狀態(tài),分別是無(wú)鎖(001)境钟、偏向鎖(101)锦担、輕量鎖(00)、重量鎖(10)和被gc標(biāo)記(11)的對(duì)象慨削。
  • 64位虛擬機(jī)對(duì)象頭.png

對(duì)象頭占據(jù)內(nèi)存

  • 例如:int是4個(gè)字節(jié)洞渔,Integer對(duì)象的Mark Word8字節(jié),Klass Word8個(gè)字節(jié)(指針壓縮后4字節(jié))缚态,存儲(chǔ)占4字節(jié)磁椒,存儲(chǔ)一個(gè)數(shù)需要占8(Mark Word)+4(Klass Word)+4(存儲(chǔ)占4字節(jié))=16字節(jié)
    驗(yàn)證new Integer(1)占據(jù)內(nèi)存大小
<!-- 查看對(duì)象偏向鎖相關(guān)信息 -->
        <dependency>
            <groupId>org.openjdk.jol</groupId>
            <artifactId>jol-core</artifactId>
            <version>0.9</version>
        </dependency>

@Slf4j(topic = "ants.TestIntegerSize")
public class TestIntegerSize {
    public static void main(String[] args) {
        Integer i = new Integer(1);
        log.debug(ClassLayout.parseInstance(i).toPrintable());
    }
}

# WARNING: Unable to attach Serviceability Agent. You can try again with escalated privileges. Two options: a) use -Djol.tryWithSudo=true to try with sudo; b) echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
2020-04-12 17:45:45.202 [main] DEBUG ants.TestIntegerSize 16 - java.lang.Integer object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           ae 22 00 f8 (10101110 00100010 00000000 11111000) (-134208850)
     12     4    int Integer.value                             1
Instance size: 16 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total
  • 由上面控制臺(tái)結(jié)果分析,new Integer(1)會(huì)占據(jù)16字節(jié)玫芦,而我們知道int i=1只會(huì)占四個(gè)字節(jié)浆熔。

Monitor(鎖) 監(jiān)視器|管程

  • 每個(gè)Java對(duì)象都可以關(guān)聯(lián)一個(gè)Monitor對(duì)象,如果使用synchronized給對(duì)象上鎖(重量級(jí)鎖)之后桥帆,該對(duì)象頭的Mark Word就被設(shè)置指向Monitor對(duì)象指針医增。


    線程-對(duì)象-Monitor關(guān)系.png
  1. synchronized(obj)使用對(duì)象鎖(obj)和Monitor對(duì)象一一對(duì)應(yīng)
  2. 剛開(kāi)始Monitor中Owner為null
  3. 當(dāng)Thread-2執(zhí)行synchronized就會(huì)將Monitor的所有者Owner置為Thread-2慎皱,Monitor中只能有一個(gè)Owner
  4. Thread在上鎖過(guò)程中,如果Thread-3叶骨,thread-4茫多,thread-5也來(lái)執(zhí)行synchronized(obj),就會(huì)進(jìn)入EntryList中進(jìn)阻塞(BLOCKED)狀態(tài)
  5. Thread-2執(zhí)行完同步代碼塊內(nèi)容邓萨,然后喚醒EntryList中等待的線程來(lái)競(jìng)爭(zhēng)鎖地梨,競(jìng)爭(zhēng)時(shí)是非公平的(synchronized沒(méi)有提供公平鎖,非公平是指如果Thread-2釋放鎖的時(shí)候來(lái)了Thread-6缔恳,那么Thread-3和Thread-6將同時(shí)有機(jī)會(huì)獲得obj對(duì)象)
  6. 圖中Thread-0宝剖,Therad-1是之前獲得過(guò)鎖,但是條件不滿足進(jìn)入WAITING狀態(tài)的線程(跟wait-notify相關(guān))

注意

  • synchronized必須是關(guān)聯(lián)統(tǒng)一個(gè)對(duì)象時(shí)歉甚,才會(huì)出現(xiàn)上面結(jié)果
  • 不加synchronized不會(huì)關(guān)聯(lián)monitor監(jiān)視器万细,不會(huì)出現(xiàn)上面結(jié)果

synchronized原理

代碼.png

代碼中對(duì)應(yīng)的字節(jié)碼.png
  • dup:將lock復(fù)制一份
  • Exception table:檢測(cè)一定范圍,如果范圍內(nèi)出現(xiàn)異常做處理
  • 6-16-19-any纸泄,表示如果在6-6行出現(xiàn)異常赖钞,java會(huì)在19行開(kāi)始執(zhí)行,同樣保存lock引用聘裁,將對(duì)象頭重置雪营,喚醒EntryList,讓其他線程競(jìng)爭(zhēng)鎖衡便,最后將處理不了的異常拋出去
  • 在字節(jié)碼中可以看出献起,即使synchronized中出現(xiàn)異常,synchronized也會(huì)釋放鎖

不同鎖

  • Monitor
  • 輕量級(jí)鎖
  • 偏向鎖
  • 批量重偏向(一個(gè)類的偏向鎖撤銷達(dá)到20閾值)
  • 一個(gè)類的偏向鎖撤銷達(dá)到40閾值镣陕,對(duì)象升級(jí)為輕量級(jí)鎖

輕量級(jí)鎖

  • 使用場(chǎng)景:如果一個(gè)對(duì)象雖然有多線程訪問(wèn)谴餐,單多線程訪問(wèn)的時(shí)間是錯(cuò)開(kāi)的(沒(méi)有線程競(jìng)爭(zhēng)),name可以用輕量級(jí)鎖來(lái)優(yōu)化呆抑。
  • 語(yǔ)法:輕量級(jí)鎖對(duì)使用這透明岂嗓,仍然使用synchronized
    輕量級(jí)鎖加鎖、解鎖流程
public class LightLock {
    static final Object object = new Object();

    public static void method1(){
        synchronized (object){
            // 同步代碼塊1
            method2();
        }
    }
    public static void method2(){
        synchronized (object){
            // 同步代碼塊2
        }
    }
}
  1. 創(chuàng)建鎖記錄(Lock Record)對(duì)象鹊碍,每個(gè)線程的棧幀都會(huì)包含一個(gè)鎖記錄厌殉,內(nèi)部可以存儲(chǔ)鎖定對(duì)象的Mark Word


    image.png
  2. 讓鎖記錄中Object Reference指向鎖對(duì)象,并嘗試使用cas替換Object的Mark Word的值存入鎖記錄


    image.png
  3. 如果替換成功侈咕,對(duì)象頭中存儲(chǔ)了鎖記錄地址和狀態(tài)00(代表輕量級(jí)鎖)年枕,表示該線程給對(duì)象加鎖,--(object對(duì)象頭中Mark Word發(fā)生變化乎完,原先01無(wú)鎖狀態(tài)變成00輕量級(jí)鎖狀態(tài)熏兄,另外分代年齡等信息變?yōu)殒i記錄地址),--(鎖記錄里面將記錄hash碼、分代年齡等信息)(--鎖記錄和Mark Word信息互換)


    image.png
  4. 如果cas失敗,分為兩種情況
    4.1 如果是其他線程已經(jīng)持有了該Object的輕量級(jí)鎖摩桶,這時(shí)表名有競(jìng)爭(zhēng)桥状,進(jìn)入鎖膨脹過(guò)程
    4.2 如果是自己執(zhí)行了synchronized表示鎖重入,那么再添加一條Lock Record作為重入的計(jì)數(shù)


    image.png
  5. 當(dāng)退出synchronized代碼塊(解鎖時(shí))硝清,如果取值為null的鎖記錄辅斟,這時(shí)重置鎖記錄,表示重入計(jì)數(shù)減一


    image.png
  6. 當(dāng)退出synchronized代碼塊(解鎖時(shí))芦拿,如果取值不為null的鎖記錄士飒,這時(shí)cas將Mark Word的值恢復(fù)給對(duì)象頭
  • 成功,則解鎖成功
  • 失敗蔗崎,說(shuō)明輕量級(jí)鎖進(jìn)程鎖膨脹已經(jīng)升級(jí)為重量級(jí)鎖酵幕,進(jìn)入重量級(jí)鎖的解鎖流程
    重量級(jí)鎖加鎖、解鎖流程
  • 如果在嘗試加輕量級(jí)鎖的過(guò)程中缓苛,cas操作無(wú)法成功芳撒,這時(shí)一種情況是其他線程為此對(duì)象加上了輕量級(jí)鎖(有競(jìng)爭(zhēng)),這時(shí)需要進(jìn)行鎖膨脹未桥,將輕量級(jí)鎖升級(jí)為重量級(jí)鎖
public class WeightLock {
    static final Object object = new Object();

    public static void method1(){
        synchronized (object){
            // 同步代碼塊1
        }
    }
}
  1. 當(dāng)Thread-1進(jìn)入輕量級(jí)鎖加鎖時(shí)笔刹,Thread-0已經(jīng)對(duì)該對(duì)象加了輕量級(jí)鎖


    image.png
  2. 這時(shí)Thread-1加鎖失敗,進(jìn)入鎖膨脹流程
    2.1 為Object對(duì)象申請(qǐng)Monitor鎖冬耿,讓Object指向重量級(jí)鎖地址
    2.2 然后線程Thread-1進(jìn)入Monitor的EntryList阻塞(BLOCKED)狀態(tài)


    image.png
  3. 當(dāng)Thread-0退出同步代碼塊解鎖時(shí)舌菜,使用cas將Mark Word的值恢復(fù)給對(duì)象頭,失敗亦镶。這時(shí)會(huì)進(jìn)入重量級(jí)解鎖流程日月,即按照Monitor地址找到Monitor對(duì)象,設(shè)置Owner為null染乌,喚醒EntryList中的BLOCKED線程
    重量級(jí)鎖競(jìng)爭(zhēng)時(shí)自旋優(yōu)化
  • 重量級(jí)鎖競(jìng)爭(zhēng)時(shí)候山孔,可以通過(guò)自旋來(lái)進(jìn)行優(yōu)化懂讯,如果當(dāng)前線程自旋成功(即這時(shí)保持鎖的新城已經(jīng)退出了同步代碼塊荷憋。釋放了鎖),這時(shí)當(dāng)前線程就可以避免阻塞
  • 以犧牲CPU褐望,多核CPU情況才能發(fā)揮優(yōu)勢(shì)
  • Java6之后自旋是自適應(yīng)的勒庄,比如對(duì)象剛剛一次自旋成功過(guò),就認(rèn)為自旋成功可能性大瘫里,就多自旋幾次实蔽;反之少自旋甚至不自旋。
  • Java7之后不能控制是否開(kāi)啟自旋功能
  • 自旋失敗后谨读,進(jìn)入EntryList阻塞(BLOCKED)狀態(tài)
    自旋重試成功.png

    偏向鎖優(yōu)化
  • 輕量級(jí)鎖不需要Monitor對(duì)象局装,使用線程棧幀中的鎖記錄充當(dāng)輕量級(jí)鎖
  • 輕量級(jí)鎖在發(fā)生鎖重入的時(shí)候,是需要cas操作,插入一條值為null的鎖記錄


    image.png
  • Java6引入偏向鎖:只有第一次使用cas將線程id設(shè)置為對(duì)象頭的Mark Word頭铐尚,之后發(fā)現(xiàn)這個(gè)線程di是自己的就表示沒(méi)有競(jìng)爭(zhēng)拨脉,不用重新cas操作。以后只要不發(fā)生競(jìng)爭(zhēng)宣增,這個(gè)對(duì)象就歸該線程所有


    image.png
  • 當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí):
    • 如果開(kāi)啟了偏向鎖(默認(rèn)開(kāi)啟)玫膀,那么對(duì)象創(chuàng)建后,markword值最后三位是101爹脾,這是它的thread帖旨、epoch、age都為0
    • 偏向鎖默認(rèn)是延遲的灵妨,不會(huì)再程序啟動(dòng)時(shí)立即生效解阅,如果想避免延遲,可以加-XX:BiasedLockingStartupDelay=0來(lái)禁用延遲
    • 如果沒(méi)有開(kāi)啟偏向鎖闷串,那么對(duì)象創(chuàng)建后瓮钥,markword值最后3位為001,這時(shí)它的hashcode烹吵、age都為0碉熄,第一次用到hashcode時(shí)才會(huì)賦值
      驗(yàn)證偏向鎖
/**
 * @author magw
 * @version 1.0
 * @date 2020/4/12 下午3:40
 * @description: No Description
 *  偏向鎖+對(duì)象內(nèi)存大小
    1).大端存儲(chǔ):大端模式,是指數(shù)據(jù)的高字節(jié)保存在內(nèi)存的低地址中肋拔,而數(shù)據(jù)的低字節(jié)保存在內(nèi)存的高地址中锈津,這樣的存儲(chǔ)模式有點(diǎn)兒類似于把數(shù)據(jù)當(dāng)作字符串順序處理:地址由小向大增加,而數(shù)據(jù)從高位往低位放凉蜂。
    2).小端存儲(chǔ):小端模式琼梆,是指數(shù)據(jù)的高字節(jié)保存在內(nèi)存的高地址中,而數(shù)據(jù)的低字節(jié)保存在內(nèi)存的低地址中窿吩,這種存儲(chǔ)模式將地址的高低和數(shù)據(jù)位權(quán)有效地結(jié)合起來(lái)茎杂,高地址部分權(quán)值高,低地址部分權(quán)值低纫雁,和我們的邏輯方法一致煌往。
 */
@Slf4j(topic = "ants.TestBiased")
public class TestBiased {
    public static void main(String[] args) {
        Object i = new Object();
        System.out.println(Integer.toHexString(i.hashCode()));
        System.out.println(ClassLayout.parseInstance(i).toPrintable());
    }
}
2280cdac
# WARNING: Unable to attach Serviceability Agent. You can try again with escalated privileges. Two options: a) use -Djol.tryWithSudo=true to try with sudo; b) echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 ac cd 80 (00000001 10101100 11001101 10000000) (-2134004735)
      4     4        (object header)                           22 00 00 00 (00100010 00000000 00000000 00000000) (34)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
  1. 從控制臺(tái)看,hacode(2280cdac)和對(duì)象頭(accd8022)hashcode(對(duì)象頭25-56)內(nèi)容不符合轧邪,這是因?yàn)槲译娔X是小端存儲(chǔ)刽脖,即數(shù)據(jù)低地址存放數(shù)據(jù)地位,應(yīng)該反來(lái)讀取忌愚,即(2280cdac)曲管,這時(shí)對(duì)象頭和hashcode對(duì)應(yīng)起來(lái)


    image.png
  2. 但是我們發(fā)現(xiàn)對(duì)象頭最低3位是001,代表是正常狀態(tài)硕糊,并不是偏向鎖狀態(tài)院水?這時(shí)因?yàn)槠蜴i默認(rèn)是延遲的腊徙,可以采取兩種方式進(jìn)行來(lái)顯示出對(duì)象頭中的偏向鎖狀態(tài)
    2.1 程序啟動(dòng)時(shí),在對(duì)象new之前睡眠>=4秒檬某,例如Thread.sleep(5000);
    2.2 設(shè)置vm啟動(dòng)參數(shù),-XX:BiasedLockingStartupDelay=0
    2.3 關(guān)閉偏向鎖:-XX:-UseBiasedLocking
  3. 線程在修改完對(duì)象頭中信息后昧穿,如果再次訪問(wèn),對(duì)象頭中的線程id不會(huì)變
public class TestBiased {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(5000);
        Object i = new Object();
        System.out.println(ClassLayout.parseInstance(i).toPrintable());
    }
}

image.png

撤銷偏向鎖

  1. 如果調(diào)用鎖對(duì)象的hashcode()方法橙喘,會(huì)撤銷對(duì)象偏向鎖时鸵,如果遇到同步,直接升級(jí)為輕量級(jí)鎖厅瞎。調(diào)用完hashcode后饰潜,線程對(duì)象頭沒(méi)有地址存放hashcode值。輕量級(jí)鎖調(diào)用hashcode后會(huì)將hashcode保存到鎖記錄里和簸,重量級(jí)鎖調(diào)用hashcode彭雾,會(huì)將hashcode保存到moitor里。
  2. 其他對(duì)象使用擁有偏向鎖對(duì)象(兩個(gè)線程交叉執(zhí)行)锁保,偏向鎖會(huì)升級(jí)輕量級(jí)鎖薯酝,當(dāng)代碼執(zhí)行后,對(duì)象的偏向鎖會(huì)撤銷
  3. 調(diào)用wait/notify后爽柒,也會(huì)撤銷偏向鎖
@Slf4j(topic = "ants.CannelBiasedMethod")
public class CannelBiasedMethod {
    public static void main(String[] args) {
        Object o = new Object();
        new Thread("t1") {
            @Override
            public void run() {
                log.debug(ClassLayout.parseInstance(o).toPrintable());
                synchronized (o){
                    log.debug(ClassLayout.parseInstance(o).toPrintable());
                }
                log.debug(ClassLayout.parseInstance(o).toPrintable());
                synchronized (CannelBiasedMethod.class){
                    CannelBiasedMethod.class.notify();
                }
            }
        }.start();
        new Thread("t2") {
            @SneakyThrows
            @Override
            public void run() {
                synchronized (CannelBiasedMethod.class){
                    CannelBiasedMethod.class.wait();
                }

                log.debug(ClassLayout.parseInstance(o).toPrintable());
                synchronized (o){
                    log.debug(ClassLayout.parseInstance(o).toPrintable());
                }
                log.debug(ClassLayout.parseInstance(o).toPrintable());
            }
        }.start();
    }
}

批量重偏向

  • 如果對(duì)象雖然被多個(gè)線程訪問(wèn)吴菠,但是沒(méi)有競(jìng)爭(zhēng),這是偏向了線程t1的對(duì)象仍有機(jī)會(huì)重新偏向t2浩村,重偏向會(huì)重置對(duì)象的Thread ID
  • 當(dāng)撤銷偏向鎖閾值超過(guò)20次后做葵,jvm會(huì)在給這些對(duì)象加鎖時(shí)重新偏向至加鎖線程
  • 線程1給對(duì)象線程id修改,t2線程獲得對(duì)象的線程id不變心墅,t2在執(zhí)行同步代碼塊時(shí)酿矢,鎖升級(jí)為輕量級(jí)鎖,同步代碼塊執(zhí)行完怎燥,對(duì)象變成無(wú)鎖狀態(tài)
  • 在達(dá)到20次后瘫筐,后面的對(duì)象中的線程id就會(huì)被修改,不會(huì)再偏向鎖-輕量級(jí)鎖-無(wú)鎖狀態(tài)轉(zhuǎn)化
//查看t2線程執(zhí)行的執(zhí)行的第19和20次铐姚,發(fā)現(xiàn)線程id變化策肝,在t2后面的線程id,不在會(huì)變化
@Slf4j(topic = "ants.BatchBiased")
public class BatchBiased {
    static Thread t1,t2;
    public static void main(String[] args) {
        int count = 39;
        Vector<Object> vector = new Vector<>();
        t1 = new Thread("t1"){
            @Override
            public void run() {
                for (int i = 0; i < count; i++) {
                    Object o = new Object();
                    vector.add(o);
                    synchronized (o) {
                        log.debug(i+"\t-----------"+ClassLayout.parseInstance(o).toPrintable());
                    }
                }
                LockSupport.unpark(t2);
            }
        };
        t1.start();

        t2 = new Thread("t2"){
            @Override
            public void run() {
                LockSupport.park();
                for (int i = 0; i < count; i++) {
                    Object o =vector.get(i);
                    log.debug(i+"\t"+"before "+ClassLayout.parseInstance(o).toPrintable());
                    synchronized (o) {
                        log.debug(i+"\t"+ClassLayout.parseInstance(o).toPrintable());
                    }
                    log.debug(i+"\t"+"after "+ClassLayout.parseInstance(o).toPrintable());
                }
            }
        };
        t2.start();
    }
}

批量撤銷

  • 當(dāng)撤銷偏向鎖超過(guò)40次后谦屑,類再新建的都是不可偏向的對(duì)象驳糯。
    鎖消除
  • JVM會(huì)在JIT字節(jié)碼進(jìn)一步優(yōu)化篇梭,會(huì)在字節(jié)碼層面優(yōu)化氢橙。會(huì)優(yōu)化掉部分代碼。
  • xx:-EliminateLocks,如果能確認(rèn)某個(gè)加鎖的對(duì)象不會(huì)逃逸出局部作用域恬偷,就可以進(jìn)行鎖刪除悍手。.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坦康,更是在濱河造成了極大的恐慌竣付,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滞欠,死亡現(xiàn)場(chǎng)離奇詭異古胆,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)筛璧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門逸绎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人夭谤,你說(shuō)我怎么就攤上這事棺牧。” “怎么了朗儒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵颊乘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我醉锄,道長(zhǎng)乏悄,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任恳不,我火速辦了婚禮纲爸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘妆够。我一直安慰自己识啦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布神妹。 她就那樣靜靜地躺著颓哮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鸵荠。 梳的紋絲不亂的頭發(fā)上冕茅,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音蛹找,去河邊找鬼姨伤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛庸疾,可吹牛的內(nèi)容都是我干的乍楚。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼届慈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼徒溪!你這毒婦竟也來(lái)了忿偷?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤臊泌,失蹤者是張志新(化名)和其女友劉穎鲤桥,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體渠概,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡茶凳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了播揪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片慧妄。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖剪芍,靈堂內(nèi)的尸體忽然破棺而出塞淹,到底是詐尸還是另有隱情,我是刑警寧澤罪裹,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布饱普,位于F島的核電站,受9級(jí)特大地震影響状共,放射性物質(zhì)發(fā)生泄漏套耕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一峡继、第九天 我趴在偏房一處隱蔽的房頂上張望冯袍。 院中可真熱鬧,春花似錦碾牌、人聲如沸康愤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)征冷。三九已至,卻和暖如春誓琼,著一層夾襖步出監(jiān)牢的瞬間检激,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工腹侣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叔收,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓傲隶,卻偏偏與公主長(zhǎng)得像饺律,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子伦籍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

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