多線程之死鎖和解決方案

什么是死鎖

線程死鎖是指由于兩個(gè)或者多個(gè)線程互相持有對(duì)方所需要的資源偎箫,導(dǎo)致這些線程處于等待狀態(tài)栋操,無法前往執(zhí)行郑藏。當(dāng)線程進(jìn)入對(duì)象的 synchronized 代碼塊時(shí)鲤孵,便占有了資源,直到它退出該代碼塊或者調(diào)用wait方法,才釋放資源赞咙,在此期間责循,其他線程將不能進(jìn)入該代碼塊。當(dāng)線程互相持有對(duì)方所需要的資源時(shí)攀操,會(huì)互相等待對(duì)方釋放資源院仿,如果線程都不主動(dòng)釋放所占有的資源,將產(chǎn)生死鎖速和。

死鎖的產(chǎn)生是必須要滿足一些特定條件的
1.互斥條件:進(jìn)程對(duì)于所分配到的資源具有排它性歹垫,即一個(gè)資源只能被一個(gè)進(jìn)程占用,直到被該進(jìn)程釋放
2.請(qǐng)求和保持條件:一個(gè)進(jìn)程因請(qǐng)求被占用資源而發(fā)生阻塞時(shí)颠放,對(duì)已獲得的資源保持不放排惨。
3.不剝奪條件:任何一個(gè)資源在沒被該進(jìn)程釋放之前,任何其他進(jìn)程都無法對(duì)他剝奪占用
4.循環(huán)等待條件:當(dāng)發(fā)生死鎖時(shí)慈迈,所等待的進(jìn)程必定會(huì)形成一個(gè)環(huán)路(類似于死循環(huán))若贮,造成永久阻塞。
一個(gè)死鎖的例子:

public class NormalDeadLock {
    private static Object valueFirst = new Object();
    private static Object valueSecond = new Object();

    private static void firstToSecond() throws InterruptedException{
        String threadName = Thread.currentThread().getName();
        synchronized (valueFirst){
            System.out.println(threadName + " get first");
            Thread.sleep(100);
            synchronized (valueSecond){
                System.out.println(threadName + " get second");
            }
        }
    }

    private static void secondToFirst() throws InterruptedException{
        String threadName = Thread.currentThread().getName();
        synchronized (valueSecond){
            System.out.println(threadName + " get second");
            Thread.sleep(100);
            synchronized (valueFirst){
                System.out.println(threadName + " get first");
            }
        }
    }

    private static class TestThread extends Thread{
        private String name;

        public TestThread(String name){
            this.name = name;
        }

        public void run(){
            Thread.currentThread().setName(name);
            try{
                secondToFirst();
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args){
        Thread.currentThread().setName("TestDeadLock");
        TestThread testThread = new TestThread("SubTestThread");
        testThread.start();
        try{
            firstToSecond();
        }catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

這個(gè)程序運(yùn)行結(jié)果:

/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/bin/java "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=57881:/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/lib/tools.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/out/production/javastudy:/Applications/IntelliJ IDEA.app/Contents/plugins/Kotlin/kotlinc/lib/kotlin-stdlib.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/Kotlin/kotlinc/lib/kotlin-reflect.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/Kotlin/kotlinc/lib/kotlin-test.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/Kotlin/kotlinc/lib/kotlin-stdlib-jdk7.jar:/Applications/IntelliJ IDEA.app/Contents/plugins/Kotlin/kotlinc/lib/kotlin-stdlib-jdk8.jar:/Users/theodore/.m2/repository/org/thymeleaf/thymeleaf/3.0.11.RELEASE/thymeleaf-3.0.11.RELEASE.jar:/Users/theodore/.m2/repository/ognl/ognl/3.1.12/ognl-3.1.12.jar:/Users/theodore/.m2/repository/org/javassist/javassist/3.20.0-GA/javassist-3.20.0-GA.jar:/Users/theodore/.m2/repository/org/attoparser/attoparser/2.0.5.RELEASE/attoparser-2.0.5.RELEASE.jar:/Users/theodore/.m2/repository/org/unbescape/unbescape/1.1.6.RELEASE/unbescape-1.1.6.RELEASE.jar:/Users/theodore/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/jaxb-api.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/gmbal-api-only.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/javax.annotation.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/ha-api.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/jaxws-api.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/jsr181-api.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/FastInoset.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/mimepull.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/mail.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/jaxws-rt.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/jaxb-impl.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/jaxb-xjc.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/policy.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/management-api.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/jaxws-tools.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/saaj-impl.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/stax-ex.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/stax2-api.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/streambuffer.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/saaj-api.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/woodstox-core-asl.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/javax.persistence.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-aspects-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-instrument-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-expression-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-context-support-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-aop-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-instrument-tomcat-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-context-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-core-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-jms-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-jdbc-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-oxm-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-messaging-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-orm-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-tx-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/commons-logging-1.2.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-test-4.3.18.RELEASE.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/aopalliance-1.0.jar:/Users/theodore/Downloads/ideaproject/xiangxue/javastudy/lib/spring-beans-4.3.18.RELEASE.jar" com.enjoy.MultiThread.ch7.NormalDeadLock
SubTestThread get second
TestDeadLock get first

程序是無法停止的痒留,因?yàn)?SubTestThread 先獲取了第二個(gè)鎖谴麦,然后去嘗試獲取第一個(gè)鎖。這個(gè)時(shí)候 TestDeadLock 先獲取了第一個(gè)鎖伸头,不釋放鎖匾效。SubTestThread 線程就一直等著。然后 TestDeadLock 在去獲取第二個(gè)鎖恤磷,這個(gè)時(shí)候第二個(gè)鎖被第一個(gè)線程占用不釋放面哼。

synchronized 不走出代碼塊是不會(huì)釋放鎖的。這就導(dǎo)致了死鎖扫步。代碼沒有保證獲得鎖的順序?qū)е铝藘蓚€(gè)線程互相等待魔策。造成死鎖。

再來看下面這個(gè)代碼:

//不安全的轉(zhuǎn)賬動(dòng)作
public class TransferAccount implements ITransfer {

    @Override
    public void transfer(UserAccount from, UserAccount to, int amout) throws InterruptedException {
        synchronized (from){//先鎖轉(zhuǎn)出
            System.out.println(Thread.currentThread().getName() + "get" + from.getName());
            Thread.sleep(100);
            synchronized (to){//后鎖轉(zhuǎn)入
                System.out.println(Thread.currentThread().getName() + "get" + to.getName());
                from.flyMoney(amout);
                to.addMoney(amout);
            }
        }
    }
}

這段代碼也會(huì)產(chǎn)生死鎖河胎,為什么呢闯袒?明明代碼保證了獲取鎖的順序呀?
對(duì)游岳,但是獲取鎖的順序是調(diào)用的時(shí)候決定的政敢,如果兩個(gè)線程,一個(gè)是 A 轉(zhuǎn)賬給 B胚迫,另一個(gè)是 B 轉(zhuǎn)賬給 A喷户。這個(gè)時(shí)候獲取鎖的順序就又不能保證了。就造成了思索访锻。
這兩段代碼第一個(gè)就是褪尝,靜態(tài)死鎖闹获,第二個(gè)就是,動(dòng)態(tài)死鎖恼五。那么怎么解決呢昌罩?有幾個(gè)解決方案:

先定義一個(gè)賬戶類 有賬戶名字和賬戶余額,還實(shí)現(xiàn)了轉(zhuǎn)入轉(zhuǎn)出方法灾馒。

//用戶賬戶實(shí)體類
public class UserAccount {

    //賬戶名字和余額
    private final String name;
    private int money;

    private final Lock lock = new ReentrantLock();

    public Lock getLock() {
        return lock;
    }

    public UserAccount(String name, int money) {
        this.name = name;
        this.money = money;
    }

    public String getName() {
        return name;
    }

    public int getMoney() {
        return money;
    }

    @Override
    public String toString() {
        return "UserAccount{" +
                "name='" + name + '\'' +
                ", money=" + money +
                ", lock=" + lock +
                '}';
    }
    //轉(zhuǎn)入金額
    public void addMoney(int amount){
        money += amount;
    }
    //轉(zhuǎn)出金額
    public void flyMoney(int amount){
        money -= amount;
    }
}

定義一個(gè)接口:

//銀行轉(zhuǎn)賬接口
public interface ITransfer {
    void transfer(UserAccount from,UserAccount to,int amout) throws InterruptedException;

}

方案1:

//不會(huì)產(chǎn)生死鎖的安全轉(zhuǎn)賬 通過hashcode保證順序
public class SafeOperate implements ITransfer {

    private static Object tieLock = new Object();//加時(shí)賽鎖

    @Override
    public void transfer(UserAccount from, UserAccount to, int amout) throws InterruptedException {
        int fromHash = System.identityHashCode(from);
        int toHash = System.identityHashCode(to);

        if(fromHash<toHash){
            synchronized (from){
                System.out.println(Thread.currentThread().getName() + "get" + from.getName());
                Thread.sleep(100);
                synchronized (to){
                    System.out.println(Thread.currentThread().getName() + "get" + to.getName());
                    from.flyMoney(amout);
                    to.addMoney(amout);
                }
            }
        }else if(toHash<fromHash){
            synchronized (to){
                System.out.println(Thread.currentThread().getName() + "get" + to.getName());
                Thread.sleep(100);
                synchronized (from){
                    System.out.println(Thread.currentThread().getName() + "get" + from.getName());
                    from.flyMoney(amout);
                    to.addMoney(amout);
                }
            }
        }else{//哈希沖突
            synchronized (tieLock){
                synchronized (from){
                    synchronized (to){
                        from.flyMoney(amout);
                        to.addMoney(amout);
                    }
                }
            }
        }
    }
}

通過兩個(gè)鎖的 hashcode 保證一定先鎖小的那個(gè),但是 hash 會(huì)有千萬分之一的沖突遣总,雖然不多睬罗,但是也需要考慮進(jìn)去。再定義一個(gè)鎖,在獲得 2 個(gè)對(duì)象的鎖之前,就要獲得這個(gè)鎖旭斥。保證順序容达。

方案2:

//用 trylock 保證不會(huì)產(chǎn)生鎖
public class SafeOperateToo implements ITransfer {
    @Override
    public void transfer(UserAccount from, UserAccount to, int amout) throws InterruptedException {
        Random r = new Random();
        while (true){
            if (from.getLock().tryLock()){
                try{
                    System.out.println(Thread.currentThread().getName() + " get " + from.getName());
                    if (to.getLock().tryLock()){
                        try{
                            System.out.println(Thread.currentThread().getName() + " get " + to.getName());
                            from.flyMoney(amout);
                            to.addMoney(amout);
                            break;
                        }finally {
                            to.getLock().unlock();
                        }
                    }
                }finally {
                    from.getLock().unlock();
                }

            }
            SleepTools.ms(r.nextInt(10));//為了保證兩個(gè)鎖之間不會(huì)互相謙讓,導(dǎo)致誰都沒有獲得鎖
        }
    }
}

上面那個(gè)代碼看起來有些麻煩垂券,這個(gè)方案花盐,用 trylock 去嘗試獲取鎖,獲取不到線程也不會(huì)阻塞菇爪,在 while 循環(huán)中會(huì)再次去嘗試獲取鎖算芯,直到獲取到了為止。但是這個(gè)有個(gè)問題凳宙,如果兩個(gè)線程同時(shí)去嘗試獲取鎖熙揍,有可能兩個(gè)線程都獲取不到,然后他們就一直重復(fù)這個(gè)動(dòng)作氏涩。雖然沒有造成死鎖届囚,但是他們都沒有繼續(xù)下面的任務(wù),這個(gè)就是活鎖是尖。為了解決這個(gè)問題意系,我們可以對(duì)重試機(jī)制引入一些隨機(jī)性,不指定同時(shí)重發(fā)饺汹,而是重發(fā)的時(shí)間內(nèi)是隨機(jī)的蛔添。通過隨機(jī)的等待再發(fā)送能夠相當(dāng)有效的避免活鎖的發(fā)生。

在定義一個(gè)類來測(cè)試我們的程序:

//模擬公司轉(zhuǎn)賬
public class PayCompay {
    private static class TransferThread extends Thread{
        private String name;
        private UserAccount from;
        private UserAccount to;
        private int amount;
        private ITransfer transfer;

        public TransferThread(String name, UserAccount from, UserAccount to, int amount, ITransfer transfer) {
            this.name = name;
            this.from = from;
            this.to = to;
            this.amount = amount;
            this.transfer = transfer;
        }

        @Override
        public void run() {
            Thread.currentThread().setName(name);
            try{
                transfer.transfer(from,to,amount);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args){
        PayCompay payCompay = new PayCompay();
        UserAccount zhangsan = new UserAccount("zhangsan",20000);
        UserAccount lisi = new UserAccount("lisi",20000);
        ITransfer transfer = new SafeOperateToo();//new SafeOperate or new TransferAccount
        TransferThread zhangsanToLisi = new TransferThread("zhangsanToLisi",zhangsan,lisi,2000,transfer);
        TransferThread lisiToZhangsan = new TransferThread("lisiToZhangsan",lisi,zhangsan,4000,transfer);
        zhangsanToLisi.start();
        lisiToZhangsan.start();
    }
}

我的代碼 github 地址: https://github.com/theodore816/javastudy/tree/master/com/enjoy/MultiThread/ch7

參考文獻(xiàn)

https://blog.csdn.net/amd123456789/article/details/80867948
https://blog.csdn.net/u011116672/article/details/51051352
https://blog.csdn.net/w1014074794/article/details/51114752
https://www.cnblogs.com/hadoop-dev/p/6899171.html
https://www.cnblogs.com/baizhanshi/p/5437933.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末首繁,一起剝皮案震驚了整個(gè)濱河市作郭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌弦疮,老刑警劉巖夹攒,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異胁塞,居然都是意外死亡咏尝,警方通過查閱死者的電腦和手機(jī)压语,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來编检,“玉大人胎食,你說我怎么就攤上這事≡识” “怎么了厕怜?”我有些...
    開封第一講書人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蕾总。 經(jīng)常有香客問我粥航,道長,這世上最難降的妖魔是什么生百? 我笑而不...
    開封第一講書人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任递雀,我火速辦了婚禮,結(jié)果婚禮上蚀浆,老公的妹妹穿的比我還像新娘缀程。我一直安慰自己,他們只是感情好市俊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開白布蛤铜。 她就那樣靜靜地躺著街氢,像睡著了一般赚抡。 火紅的嫁衣襯著肌膚如雪掷匠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,856評(píng)論 1 290
  • 那天据忘,我揣著相機(jī)與錄音鹦牛,去河邊找鬼。 笑死勇吊,一個(gè)胖子當(dāng)著我的面吹牛曼追,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播汉规,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼礼殊,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了针史?” 一聲冷哼從身側(cè)響起晶伦,我...
    開封第一講書人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎啄枕,沒想到半個(gè)月后婚陪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡频祝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年泌参,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脆淹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沽一,死狀恐怖盖溺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情铣缠,我是刑警寧澤烘嘱,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布,位于F島的核電站攘残,受9級(jí)特大地震影響拙友,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜歼郭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辐棒。 院中可真熱鬧病曾,春花似錦、人聲如沸漾根。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辐怕。三九已至逼蒙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間寄疏,已是汗流浹背是牢。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留陕截,地道東北人驳棱。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像农曲,于是被迫代替她去往敵國和親社搅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

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