JAVA 并發(fā) 編程系列 (一 ) 基本 銜接 深入理解JVM

一 并發(fā)編程的挑戰(zhàn)

1蒲赂、上下文切換

  • 即使是單核處理器也支持多線程執(zhí)行代碼水醋,CPU通過給每個(gè)線程分配CPU時(shí)間片來實(shí)現(xiàn)
    這個(gè)機(jī)制葛碧。時(shí)間片是CPU分配給各個(gè)線程的時(shí)間,因?yàn)闀r(shí)間片非常短粪狼,所以CPU通過不停地切
    換線程執(zhí)行,讓我們感覺多個(gè)線程是同時(shí)執(zhí)行的任岸,時(shí)間片一般是幾十毫秒(ms)再榄。
  • CPU通過時(shí)間片分配算法來循環(huán)執(zhí)行任務(wù),當(dāng)前任務(wù)執(zhí)行一個(gè)時(shí)間片后會(huì)切換到下一個(gè)
    任務(wù)享潜。但是困鸥,在切換前會(huì)保存上一個(gè)任務(wù)的狀態(tài),以便下次切換回這個(gè)任務(wù)時(shí)剑按,可以再加載這
    個(gè)任務(wù)的狀態(tài)窝革。所以任務(wù)從保存到再加載的過程就是一次上下文切換
  • 這就像我們同時(shí)讀兩本書购城,當(dāng)我們?cè)谧x一本英文的技術(shù)書時(shí),發(fā)現(xiàn)某個(gè)單詞不認(rèn)識(shí)虐译,于是
    便打開中英文字典瘪板,但是在放下英文技術(shù)書之前,大腦必須先記住這本書讀到了多少頁的第
    多少行漆诽,等查完單詞之后侮攀,能夠繼續(xù)讀這本書。這樣的切換是會(huì)影響讀書效率的厢拭,同樣上下文
    切換也會(huì)影響多線程的執(zhí)行速度兰英。

1.1如何減少上下文切換

減少上下文切換的方法有無鎖并發(fā)編程供鸠、CAS算法畦贸、使用最少線程和使用協(xié)程。
  • 無鎖并發(fā)編程楞捂。多線程競(jìng)爭(zhēng)鎖時(shí)薄坏,會(huì)引起上下文切換,所以多線程處理數(shù)據(jù)時(shí)寨闹,可以用一
    些辦法來避免使用鎖胶坠,如將數(shù)據(jù)的ID按照Hash算法取模分段,不同的線程處理不同段的數(shù)據(jù)繁堡。
  • CAS算法沈善。Java的Atomic包使用CAS算法來更新數(shù)據(jù),而不需要加鎖椭蹄。
  • 使用最少線程闻牡。避免創(chuàng)建不需要的線程,比如任務(wù)很少绳矩,但是創(chuàng)建了很多線程來處理澈侠,這
    樣會(huì)造成大量線程都處于等待狀態(tài)。
  • 協(xié)程:在單線程里實(shí)現(xiàn)多任務(wù)的調(diào)度埋酬,并在單線程里維持多個(gè)任務(wù)間的切換哨啃。
實(shí)戰(zhàn)
  • 第一步:用jstack命令dump線程信息,看看pid為3117的進(jìn)程里的線程都在做什么写妥。
    sudo -u admin /opt/ifeve/java/bin/jstack 31177 > /home/tengfei.fangtf/dump17
  • 第二步:統(tǒng)計(jì)所有線程分別處于什么狀態(tài)拳球,發(fā)現(xiàn)300多個(gè)線程處于WAITING(onobject-
    monitor)狀態(tài)。
[tengfei.fangtf@ifeve ~]$ grep java.lang.Thread.State dump17 | awk '{print $2$3$4$5}'
| sort | uniq -c
39 RUNNABLE
21 TIMED_WAITING(onobjectmonitor)
6 TIMED_WAITING(parking)
51 TIMED_WAITING(sleeping)
305 WAITING(onobjectmonitor)
3 WAITING(parking)
  • 第三步:打開dump文件查看處于WAITING(onobjectmonitor)的線程在做什么珍特。發(fā)現(xiàn)這些線
    程基本全是JBOSS的工作線程祝峻,在await。說明JBOSS線程池里線程接收到的任務(wù)太少,大量線
    程都閑著莱找。

2 酬姆、 死鎖

避免死鎖的幾個(gè)常見方法。

  • 避免一個(gè)線程同時(shí)獲取多個(gè)鎖
  • ·避免一個(gè)線程在鎖內(nèi)同時(shí)占用多個(gè)資源奥溺,盡量保證每個(gè)鎖只占用一個(gè)資源辞色。
  • ·嘗試使用定時(shí)鎖,使用lock.tryLock(timeout)來替代使用內(nèi)部鎖機(jī)制浮定。
  • ·對(duì)于數(shù)據(jù)庫鎖相满,加鎖和解鎖必須在一個(gè)數(shù)據(jù)庫連接里,否則會(huì)出現(xiàn)解鎖失敗的情況桦卒。

3立美、資源限制的挑戰(zhàn)

什么是資源限制?

  • 服務(wù)器的帶寬只有2Mb/s方灾,某個(gè)資源的下載速度是1Mb/s每秒建蹄,系統(tǒng)啟動(dòng)10個(gè)線程下載資
    源,下載速度不會(huì)變成10Mb/s
  • 在進(jìn)行并發(fā)編程時(shí)裕偿,要考慮這些資源的限制洞慎。硬件資源限
    制有帶寬的上傳/下載速度、硬盤讀寫速度和CPU的處理速度击费。軟件資源限制有數(shù)據(jù)庫的連接
    數(shù)和socket連接數(shù)等。

資源限制引發(fā)的問題

  • 將代碼中串行執(zhí)行的部分變成并發(fā)執(zhí)行桦他,但是如果將某段串行的代碼并發(fā)執(zhí)行蔫巩,因?yàn)槭芟抻谫Y源,仍然在串行執(zhí)行快压,這時(shí)候程序不僅不
    會(huì)加快執(zhí)行圆仔,反而會(huì)更慢,因?yàn)樵黾恿松舷挛那袚Q和資源調(diào)度的時(shí)間蔫劣。

如何解決資源限制的問題

  • 硬件資源限制 坪郭,既然單機(jī)的資源有限制,那么就讓
    程序在多機(jī)上運(yùn)行脉幢。 使用集群歪沃。不同的機(jī)器處理不同
    的數(shù)據(jù)∠铀桑可以通過“數(shù)據(jù)ID%機(jī)器數(shù)”沪曙,計(jì)算得到一個(gè)機(jī)器編號(hào),然后由對(duì)應(yīng)編號(hào)的機(jī)器處理這
    筆數(shù)據(jù)萎羔。
  • 軟件資源限制液走,可以考慮使用資源池將資源復(fù)用。比如使用連接池將數(shù)據(jù)庫和Socket
    連接復(fù)用,或者在調(diào)用對(duì)方webservice接口獲取數(shù)據(jù)時(shí)缘眶,只建立一個(gè)連接嘱根。

二 、Java并發(fā)機(jī)制的底層實(shí)現(xiàn)原理

Java代碼在編譯后會(huì)變成Java字節(jié)碼巷懈,字節(jié)碼被類加載器加載到JVM里该抒,JVM執(zhí)行字節(jié)碼,最終需要轉(zhuǎn)化為匯編指令在CPU上執(zhí)行砸喻,Java中所使用的并發(fā)機(jī)制依賴于JVM的實(shí)現(xiàn)和CPU的指令柔逼。

volatile的應(yīng)用

  • volatile的定義與實(shí)現(xiàn)原理
    • 定義: Java語言規(guī)范第3版中對(duì)volatile的定義如下:Java編程語言允許線程訪問共享變量,為了
      確保共享變量能被準(zhǔn)確和一致地更新割岛,線程應(yīng)該確保通過排他鎖單獨(dú)獲得這個(gè)變量愉适。Java語言
      提供了volatile,在某些情況下比鎖要更加方便癣漆。如果一個(gè)字段被聲明成volatile维咸,Java線程內(nèi)存
      模型確保所有線程看到這個(gè)變量的值是一致的
  • CPU的術(shù)語定義


    mark

volatile是如何來保證可見性的呢? 看下反編譯之后的

Java代碼如下。
instance = new Singleton(); // instance是volatile變量
轉(zhuǎn)變成匯編代碼惠爽,如下癌蓖。
0x01a3de1d: movb $0×0,0×1104800(%esi);0x01a3de24: lock addl $0×0,(%esp);

有volatile變量修飾的共享變量進(jìn)行寫操作的時(shí)候會(huì)多出第二行匯編代碼
,Lock前綴的指令在多核處理器下會(huì)引發(fā)了兩件事情

  • 將當(dāng)前處理器緩存行的數(shù)據(jù)寫回到系統(tǒng)內(nèi)存婚肆。
  • 這個(gè)寫回內(nèi)存的操作會(huì)使在其他CPU里緩存了該內(nèi)存地址的數(shù)據(jù)無效
  • JVM就會(huì)向處理器發(fā)送一條Lock前綴的指令租副,將這個(gè)變量所在緩存行的數(shù)據(jù)
    寫回到系統(tǒng)內(nèi)存。但是较性,就算寫回到內(nèi)存用僧,如果其他處理器緩存的值還是舊的,再執(zhí)行計(jì)算操
    作就會(huì)有問題赞咙。所以责循,在多處理器下,為了保證各個(gè)處理器的緩存是一致的攀操,就會(huì)實(shí)現(xiàn)緩存一
    致性協(xié)議院仿,每個(gè)處理器通過嗅探在總線上傳播的數(shù)據(jù)來檢查自己緩存的值是不是過期了,當(dāng)
    處理器發(fā)現(xiàn)自己緩存行對(duì)應(yīng)的內(nèi)存地址被修改速和,就會(huì)將當(dāng)前處理器的緩存行設(shè)置成無效狀
    態(tài)歹垫,當(dāng)處理器對(duì)這個(gè)數(shù)據(jù)進(jìn)行修改操作的時(shí)候,會(huì)重新從系統(tǒng)內(nèi)存中把數(shù)據(jù)讀到處理器緩存
    里颠放。

volatile的兩條實(shí)現(xiàn)原則

  • Lock前綴指令會(huì)引起處理器緩存回寫到內(nèi)存
  • 一個(gè)處理器的緩存回寫到內(nèi)存會(huì)導(dǎo)致其他處理器的緩存無效(例如县钥,在Pentium和P6 family處理器中,如果通過嗅探一個(gè)處理
    器來檢測(cè)其他處理器打算寫內(nèi)存地址慈迈,而這個(gè)地址當(dāng)前處于共享狀態(tài)若贮,那么正在嗅探的處理
    器將使它的緩存行無效省有,在下次訪問相同內(nèi)存地址時(shí),強(qiáng)制執(zhí)行緩存行填充谴麦。)

synchronized的實(shí)現(xiàn)原理與應(yīng)用

Java中的每一個(gè)對(duì)象都可以作為鎖蠢沿。具體表現(xiàn)為以下3種形式。
  • 對(duì)于普通同步方法匾效,鎖是當(dāng)前實(shí)例對(duì)象舷蟀。
  • 對(duì)于靜態(tài)同步方法,鎖是當(dāng)前類的Class對(duì)象面哼。
  • 對(duì)于同步方法塊野宜,鎖是Synchonized括號(hào)里配置的對(duì)象。

代碼塊同步是使用monitorenter
和monitorexit指令實(shí)現(xiàn)的

任何對(duì)象都有一個(gè)monitor與之關(guān)聯(lián)魔策,當(dāng)且一個(gè)monitor被持有后匈子,它將處于鎖定狀態(tài)。線程執(zhí)行到monitorenter指令時(shí)闯袒,將會(huì)嘗試獲取對(duì)象所對(duì)應(yīng)的monitor的所有權(quán)虎敦,即嘗試獲得對(duì)象的鎖

mark

mark

鎖的升級(jí)與對(duì)比


Java SE 1.6中,鎖一共有4種狀態(tài)政敢,級(jí)別從低到高依次是:無鎖狀態(tài)其徙、偏向鎖狀態(tài)、輕量級(jí)鎖狀
態(tài)和重量級(jí)鎖狀態(tài)
喷户,這幾個(gè)狀態(tài)會(huì)隨著競(jìng)爭(zhēng)情況逐漸升級(jí)唾那。鎖可以升級(jí)但不能降級(jí),意味著偏
向鎖升級(jí)成輕量級(jí)鎖后不能降級(jí)成偏向鎖褪尝。這種鎖升級(jí)卻不能降級(jí)的策略闹获,目的是為了提高
獲得鎖和釋放鎖的效率

1.偏向鎖

  • 大多數(shù)情況下,鎖不僅不存在多線程競(jìng)爭(zhēng)恼五,而且總是由同
    一線程多次獲得昌罩,為了讓線程獲得鎖的代價(jià)更低而引入了偏向鎖哭懈。當(dāng)一個(gè)線程訪問同步塊并
    獲取鎖時(shí)灾馒,會(huì)在對(duì)象頭和棧幀中的鎖記錄里存儲(chǔ)鎖偏向的線程ID,以后該線程在進(jìn)入和退出
    同步塊時(shí)不需要進(jìn)行CAS操作來加鎖和解鎖遣总,只需簡(jiǎn)單地測(cè)試一下對(duì)象頭的Mark Word里是否
    存儲(chǔ)著指向當(dāng)前線程的偏向鎖睬罗。如果測(cè)試成功,表示線程已經(jīng)獲得了鎖
  • 如果測(cè)試失敗旭斥,則需
    要再測(cè)試一下Mark Word中偏向鎖的標(biāo)識(shí)是否設(shè)置成1(表示當(dāng)前是偏向鎖):如果沒有設(shè)置容达,則
    使用CAS競(jìng)爭(zhēng)鎖;如果設(shè)置了垂券,則嘗試使用CAS將對(duì)象頭的偏向鎖指向當(dāng)前線程花盐。
mark
偏向鎖在Java 6和Java 7里是默認(rèn)啟用的羡滑,但是它在應(yīng)用程序啟動(dòng)幾秒鐘之后才激活,如有必要可以使用JVM參數(shù)來關(guān)閉延遲:-XX:BiasedLockingStartupDelay=0算芯。如果你確定應(yīng)用程序里所有的鎖通常情況下處于競(jìng)爭(zhēng)狀態(tài)柒昏,可以通過JVM參數(shù)關(guān)閉偏向鎖:-XX:-UseBiasedLocking=false,那么程序默認(rèn)會(huì)進(jìn)入輕量級(jí)鎖狀態(tài)熙揍。

2.輕量級(jí)鎖

  • 輕量級(jí)鎖加鎖

線程在執(zhí)行同步塊之前职祷,JVM會(huì)先在當(dāng)前線程的棧楨中創(chuàng)建用于存儲(chǔ)鎖記錄的空間,并
將對(duì)象頭中的Mark Word復(fù)制到鎖記錄中届囚,官方稱為Displaced Mark Word有梆。然后線程嘗試使用
CAS將對(duì)象頭中的Mark Word替換為指向鎖記錄的指針。如果成功意系,當(dāng)前線程獲得鎖泥耀,如果失
敗,表示其他線程競(jìng)爭(zhēng)鎖昔字,當(dāng)前線程便嘗試使用自旋來獲取鎖

  • 輕量級(jí)鎖解鎖

輕量級(jí)解鎖時(shí)爆袍,會(huì)使用原子的CAS操作將Displaced Mark Word替換回到對(duì)象頭,如果成
功作郭,則表示沒有競(jìng)爭(zhēng)發(fā)生陨囊。如果失敗,表示當(dāng)前鎖存在競(jìng)爭(zhēng)夹攒,鎖就會(huì)膨脹成重量級(jí)鎖蜘醋。

mark
因?yàn)樽孕龝?huì)消耗CPU,為了避免無用的自旋(比如獲得鎖的線程被阻塞住了)咏尝,一旦鎖升級(jí)成重量級(jí)鎖压语,就不會(huì)再恢復(fù)到輕量級(jí)鎖狀態(tài)。當(dāng)鎖處于這個(gè)狀態(tài)下编检,其他線程試圖獲取鎖時(shí)胎食,都會(huì)被阻塞住,當(dāng)持有鎖的線程釋放鎖之后會(huì)喚醒這些線程允懂,被喚醒的線程就會(huì)進(jìn)行新一輪的奪鎖之爭(zhēng)厕怜。
mark

原子操作的實(shí)現(xiàn)原理

java 實(shí)現(xiàn) 原子操作

  • (1)使用循環(huán)CAS實(shí)現(xiàn)原子操作

JVM中的CAS操作正是利用了處理器提供的CMPXCHG指令實(shí)現(xiàn)的。自旋CAS實(shí)現(xiàn)的基本
思路就是循環(huán)進(jìn)行CAS操作直到成功為止蕾总,以下代碼實(shí)現(xiàn)了一個(gè)基于CAS線程安全的計(jì)數(shù)器
方法safeCount和一個(gè)非線程安全的計(jì)數(shù)器count粥航。

public class Counter {

    private AtomicInteger atomicI = new AtomicInteger(0);
    private int           i       = 0;

    public static void main(String[] args) {
        final Counter cas = new Counter();
        List<Thread> ts = new ArrayList<Thread>(600);
        long start = System.currentTimeMillis();
        for (int j = 0; j < 100; j++) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10000; i++) {
                        cas.count();
                        cas.safeCount();
                    }
                }
            });
            ts.add(t);
        }
        for (Thread t : ts) {
            t.start();

        }
        // 等待所有線程執(zhí)行完成
        for (Thread t : ts) {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        System.out.println(cas.i);
        System.out.println(cas.atomicI.get());
        System.out.println(System.currentTimeMillis() - start);
    }

    /**
     * 使用CAS實(shí)現(xiàn)線程安全計(jì)數(shù)器
     */
    private void safeCount() {
        for (;;) {
            int i = atomicI.get();
            boolean suc = atomicI.compareAndSet(i, ++i);
            if (suc) {
                break;
            }
        }
    }

    /**
     * 非線程安全計(jì)數(shù)器
     */
    private void count() {
        i++;
    }

}

  • (2)CAS實(shí)現(xiàn)原子操作的三大問題
1)ABA問題。

因?yàn)镃AS需要在操作值的時(shí)候生百,檢查值有沒有發(fā)生變化递雀,如果沒有發(fā)生變化
則更新,但是如果一個(gè)值原來是A蚀浆,變成了B缀程,又變成了A搜吧,那么使用CAS進(jìn)行檢查時(shí)會(huì)發(fā)現(xiàn)它
的值沒有發(fā)生變化,但是實(shí)際上卻變化了杨凑。ABA問題的解決思路就是使用版本號(hào)赎败。在變量前面
追加上版本號(hào),每次變量更新的時(shí)候把版本號(hào)加1蠢甲,那么A→B→A就會(huì)變成1A→2B→3A僵刮。從
Java 1.5開始,JDK的Atomic包里提供了一個(gè)類AtomicStampedReference來解決ABA問題鹦牛。這個(gè)
類的compareAndSet方法的作用是首先檢查當(dāng)前引用是否等于預(yù)期引用搞糕,并且檢查當(dāng)前標(biāo)志是
否等于預(yù)期標(biāo)志,如果全部相等曼追,則以原子方式將該引用和該標(biāo)志的值設(shè)置為給定的更新值窍仰。

public boolean compareAndSet(
V expectedReference, // 預(yù)期引用
V newReference, // 更新后的引用
int expectedStamp, // 預(yù)期標(biāo)志
int newStamp // 更新后的標(biāo)志
)
2)循環(huán)時(shí)間長(zhǎng)開銷大。

自旋CAS如果長(zhǎng)時(shí)間不成功礼殊,會(huì)給CPU帶來非常大的執(zhí)行開銷驹吮。如
果JVM能支持處理器提供的pause指令,那么效率會(huì)有一定的提升晶伦。pause指令有兩個(gè)作用:第
一碟狞,它可以延遲流水線執(zhí)行指令(de-pipeline),使CPU不會(huì)消耗過多的執(zhí)行資源婚陪,延遲的時(shí)間
取決于具體實(shí)現(xiàn)的版本族沃,在一些處理器上延遲時(shí)間是零;第二泌参,它可以避免在退出循環(huán)的時(shí)候
因內(nèi)存順序沖突(Memory Order Violation)而引起CPU流水線被清空(CPU Pipeline Flush)脆淹,從而
提高CPU的執(zhí)行效率。

3)只能保證一個(gè)共享變量的原子操作

當(dāng)對(duì)一個(gè)共享變量執(zhí)行操作時(shí)沽一,我們可以使用循
環(huán)CAS的方式來保證原子操作盖溺,但是對(duì)多個(gè)共享變量操作時(shí),循環(huán)CAS就無法保證操作的原子
性铣缠,這個(gè)時(shí)候就可以用鎖烘嘱。還有一個(gè)取巧的辦法,就是把多個(gè)共享變量合并成一個(gè)共享變量來
操作攘残。比如拙友,有兩個(gè)共享變量i=2为狸,j=a歼郭,合并一下ij=2a,然后用CAS來操作ij辐棒。從Java 1.5開始病曾,
JDK提供了AtomicReference類來保證引用對(duì)象之間的原子性牍蜂,就可以把多個(gè)變量放在一個(gè)對(duì)
象里來進(jìn)行CAS操作。

  • (3)使用鎖機(jī)制實(shí)現(xiàn)原子操作

鎖機(jī)制保證了只有獲得鎖的線程才能夠操作鎖定的內(nèi)存區(qū)域泰涂。JVM內(nèi)部實(shí)現(xiàn)了很多種鎖
機(jī)制鲫竞,有偏向鎖、輕量級(jí)鎖和互斥鎖逼蒙。有意思的是除了偏向鎖从绘,JVM實(shí)現(xiàn)鎖的方式都用了循環(huán)
CAS,即當(dāng)一個(gè)線程想進(jìn)入同步塊的時(shí)候使用循環(huán)CAS的方式來獲取鎖是牢,當(dāng)它退出同步塊的時(shí)
候使用循環(huán)CAS釋放鎖僵井。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市驳棱,隨后出現(xiàn)的幾起案子批什,更是在濱河造成了極大的恐慌,老刑警劉巖社搅,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件驻债,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡形葬,警方通過查閱死者的電腦和手機(jī)合呐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笙以,“玉大人合砂,你說我怎么就攤上這事≡粗” “怎么了翩伪?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)谈息。 經(jīng)常有香客問我缘屹,道長(zhǎng),這世上最難降的妖魔是什么侠仇? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任轻姿,我火速辦了婚禮,結(jié)果婚禮上逻炊,老公的妹妹穿的比我還像新娘互亮。我一直安慰自己,他們只是感情好余素,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布豹休。 她就那樣靜靜地躺著,像睡著了一般桨吊。 火紅的嫁衣襯著肌膚如雪威根。 梳的紋絲不亂的頭發(fā)上凤巨,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音洛搀,去河邊找鬼敢茁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛留美,可吹牛的內(nèi)容都是我干的彰檬。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼谎砾,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼僧叉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起棺榔,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤瓶堕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后症歇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體郎笆,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年忘晤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宛蚓。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡设塔,死狀恐怖凄吏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闰蛔,我是刑警寧澤痕钢,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站序六,受9級(jí)特大地震影響任连,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜例诀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一随抠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧繁涂,春花似錦拱她、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春氧猬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背坏瘩。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工盅抚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人倔矾。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓妄均,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親哪自。 傳聞我的和親對(duì)象是個(gè)殘疾皇子丰包,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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