java并發(fā)(2)線程詳解

什么是線程

線程(thread) 是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位。它被包含在進(jìn)程之中售貌,是進(jìn)程中的實(shí)際運(yùn)作單位伞鲫。一條線程指的是進(jìn)程中一個(gè)單一順序的控制流拗秘,一個(gè)進(jìn)程中可以并發(fā)多個(gè)線程,每條線程并行執(zhí)行不同的任務(wù)草穆。

線程由線程ID灌灾,程序計(jì)數(shù)器(PC)[用于指向內(nèi)存中的程序指令],寄存器集合[由于存放本地變量和臨時(shí)變量]和堆棧[用于存放方法指令和方法參數(shù)等]組成悲柱。

線程狀態(tài)

Java線程中,有一個(gè)內(nèi)部枚舉類 State,里面定義了Java線程的六種狀態(tài).

狀態(tài)名 說明
NEW 初始狀態(tài),線程被構(gòu)建,但是還沒調(diào)用start()方法
RUNNABLE 處于可運(yùn)行狀態(tài)的線程正在Java虛擬機(jī)中執(zhí)行锋喜,
但它可能正在等待來自操作系統(tǒng)(例如處理器)的其他資源。
對應(yīng)操作系統(tǒng)中的就緒和運(yùn)行狀態(tài)
BLOCKED 阻塞狀態(tài), 線程正在處于等待鎖的狀態(tài)
WAITING 等待狀態(tài),表示當(dāng)前線程需要等待其他線程喚醒或中斷.
TIMED_WAITING 超時(shí)等待狀態(tài),不同于 WAITING,他可以在指定的時(shí)間內(nèi)自行返回
TERMINATED 終止?fàn)顟B(tài), 表示當(dāng)前線程已經(jīng)執(zhí)行完畢
java線程狀態(tài).png

阻塞狀態(tài)是線程阻塞在進(jìn)入synchronized方法或方法塊(等待獲取鎖)的狀態(tài), 但是阻塞在 JUC中 Lock接口的線程狀態(tài)確實(shí)等待狀態(tài),因?yàn)镴UC是使用LockSupport相關(guān)方法來實(shí)現(xiàn)阻塞.

線程優(yōu)先級

現(xiàn)代操作系統(tǒng)基本采用時(shí)分的形式調(diào)度運(yùn)行的線程豌鸡,操作系統(tǒng)會分出一個(gè)個(gè)時(shí)間片嘿般,線程會分配到若干時(shí)間片,當(dāng)線程的時(shí)間片用完了就會發(fā)生線程調(diào)度直颅,并等待著下次分配博个。線程分配到的時(shí)間片多少也就決定了線程使用處理器資源的多少,而線程優(yōu)先級就是決定線程需要多或者少分配一些處理器資源的線程屬性功偿。

在Java線程中盆佣,通過一個(gè)整型成員變量priority來控制優(yōu)先級往堡,優(yōu)先級的范圍從1~10,在線程構(gòu)建的時(shí)候可以通過setPriority(int)方法來修改優(yōu)先級共耍,默認(rèn)優(yōu)先級是5虑灰,優(yōu)先級高的線程分配時(shí)間片的數(shù)量要多于優(yōu)先級低的線程。設(shè)置線程優(yōu)先級時(shí)痹兜,針對頻繁阻塞(休眠或者I/O操作)的線程需要設(shè)置較高優(yōu)先級穆咐,而偏重計(jì)算(需要較多CPU時(shí)間或者偏運(yùn)算)的線程則設(shè)置較低的優(yōu)先級,確保處理器不會被獨(dú)占字旭。

線程的優(yōu)先級在一些系統(tǒng)中可能不會生效. 即該方法不能保證線程的優(yōu)先級,只能當(dāng)做輔助.

public class Priority {
    public static void main(String[] args) throws Exception {

        Thread.currentThread().setPriority(10);
        Thread t = null;
        for (int i = 1; i < 10; i++) {
            t = new Thread(new JustWaitRunnable(), "thread priority " + i);
            t.setPriority(i);
            t.start();
        }
        t.join();
    }

    private static class JustWaitRunnable implements Runnable {
        @Override
        public void run() {
            while (true) {
                try {
                    TimeUnit.MILLISECONDS.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

使用 jps指令查找對應(yīng)的java進(jìn)程號.

使用 jstack pid 查看java進(jìn)程具體的信息.

在windows上運(yùn)行的jstack信息:

"main" #1 prio=10 os_prio=2 tid=0x00000000036b3800 nid=0x7fc4 in Object.wait() [0x00000000036af000]
   java.lang.Thread.State: WAITING (on object monitor)

"thread priority 9" #18 prio=9 os_prio=2 tid=0x000000001e262000 nid=0x7d7c waiting on condition [0x000000001f51f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 8" #17 prio=8 os_prio=1 tid=0x000000001e261800 nid=0xdfc waiting on condition [0x000000001f41f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 7" #16 prio=7 os_prio=1 tid=0x000000001e25c800 nid=0x7d94 waiting on condition [0x000000001f31f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 6" #15 prio=6 os_prio=0 tid=0x000000001e258000 nid=0x7edc waiting on condition [0x000000001f21e000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 5" #14 prio=5 os_prio=0 tid=0x000000001e257000 nid=0x23d4 waiting on condition [0x000000001f11e000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 4" #13 prio=4 os_prio=-1 tid=0x000000001e256800 nid=0x7c74 waiting on condition [0x000000001f01f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 3" #12 prio=3 os_prio=-1 tid=0x000000001e253800 nid=0x7a98 waiting on condition [0x000000001ef1e000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 2" #11 prio=2 os_prio=-2 tid=0x000000001e23f800 nid=0x7e6c waiting on condition [0x000000001ee1f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 1" #10 prio=1 os_prio=-2 tid=0x000000001e23e800 nid=0x7fdc waiting on condition [0x000000001ed1f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

從上面可以看出,在windows平臺上, java優(yōu)先級和對應(yīng)的內(nèi)核優(yōu)先級的關(guān)系.

Java線程優(yōu)先級 內(nèi)核線程對應(yīng)的優(yōu)先級
1,2 -2
3,4 -1
5,6 0
7,8 1
9,10 2

在mac上的jstack信息

"main" #1 prio=10 os_prio=31 tid=0x00007fea1c800800 nid=0x1103 in Object.wait() [0x00007000016d2000]
   java.lang.Thread.State: WAITING (on object monitor)

"thread priority 9" #17 prio=9 os_prio=31 tid=0x00007fea1c83b000 nid=0x5803 waiting on condition [0x0000700002e1a000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 8" #16 prio=8 os_prio=31 tid=0x00007fea1b041800 nid=0xa703 waiting on condition [0x0000700002d17000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 7" #15 prio=7 os_prio=31 tid=0x00007fea1c83a000 nid=0xa803 waiting on condition [0x0000700002c14000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 6" #14 prio=6 os_prio=31 tid=0x00007fea1b040800 nid=0x5503 waiting on condition [0x0000700002b11000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 5" #13 prio=5 os_prio=31 tid=0x00007fea1c839800 nid=0x4503 waiting on condition [0x0000700002a0e000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 4" #12 prio=4 os_prio=31 tid=0x00007fea1b040000 nid=0x4403 waiting on condition [0x000070000290b000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 3" #11 prio=3 os_prio=31 tid=0x00007fea1c838800 nid=0x4903 waiting on condition [0x0000700002808000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 2" #10 prio=2 os_prio=31 tid=0x00007fea1c026800 nid=0x4a03 waiting on condition [0x0000700002705000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

"thread priority 1" #9 prio=1 os_prio=31 tid=0x00007fea1b853000 nid=0x4b03 waiting on condition [0x0000700002602000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)

線程優(yōu)先級不能作為程序正確性的依賴对湃,因?yàn)椴僮飨到y(tǒng)可以完全不用理會Java 線程對于優(yōu)先級的設(shè)定。
從上面可以看出,在mac系統(tǒng)中, java線程優(yōu)先級的設(shè)置是無效的, 對應(yīng)的系統(tǒng)線程優(yōu)先級都是 31.

另一個(gè)例子 :

public class Priority {
    private static volatile boolean notStart = true;
    private static volatile boolean notEnd   = true;

    public static void main(String[] args) throws Exception {
        List<Job> jobs = new ArrayList<Job>();
        for (int i = 1; i < 11; i++) {
            Job job = new Job(i);
            jobs.add(job);
            Thread thread = new Thread(job, "Thread:" + i);
            thread.setPriority(i);
            thread.start();
        }
        notStart = false;
        Thread.currentThread().setPriority(8);
        System.out.println("done.");
        TimeUnit.SECONDS.sleep(5);
        notEnd = false;

        jobs.sort(Comparator.comparingInt(o -> o.jobCount));
        for (Job job : jobs) {
            System.out.println("Job Priority : " + job.priority + ", Count : " + job.jobCount);
        }
    }

    static class Job implements Runnable {
        private final int priority;
        private       int jobCount;

        public Job(int priority) {
            this.priority = priority;
        }

        public void run() {
            while (notStart) {
                Thread.yield();
            }
            while (notEnd) {
                Thread.yield();
                jobCount++;
            }
        }
    }
}

在windows上運(yùn)行:

Job Priority : 2, Count : 102
Job Priority : 1, Count : 318
Job Priority : 3, Count : 10518
Job Priority : 4, Count : 10667
Job Priority : 6, Count : 1113314
Job Priority : 5, Count : 1113323
Job Priority : 7, Count : 1874817
Job Priority : 8, Count : 1875519
Job Priority : 10, Count : 2133667
Job Priority : 9, Count : 2135421

在Mac上運(yùn)行:

Job Priority : 5, Count : 417774
Job Priority : 2, Count : 417997
Job Priority : 3, Count : 418077
Job Priority : 1, Count : 418094
Job Priority : 4, Count : 418203
Job Priority : 9, Count : 418218
Job Priority : 8, Count : 418237
Job Priority : 7, Count : 418299
Job Priority : 6, Count : 418416
Job Priority : 10, Count : 418463

在Android手機(jī)中運(yùn)行:

Job Priority : 2, Count : 1332
Job Priority : 1, Count : 1827
Job Priority : 4, Count : 4250
Job Priority : 3, Count : 24189
Job Priority : 5, Count : 501642
Job Priority : 6, Count : 709992
Job Priority : 7, Count : 1181706
Job Priority : 8, Count : 1906252
Job Priority : 9, Count : 2342730
Job Priority : 10, Count : 2967839

Daemon線程

Daemon線程是一種支持型線程遗淳,因?yàn)樗饕挥米鞒绦蛑泻笈_調(diào)度以及支持性工作拍柒。這意味著,當(dāng)一個(gè)Java虛擬機(jī)中不存在非Daemon線程的時(shí)候屈暗,Java虛擬機(jī)將會退出拆讯。

可以通過調(diào) 用Thread.setDaemon(true)將線程設(shè)置為Daemon線程。Daemon屬性需要在啟動線程之前設(shè)置养叛,不能在啟動線程之后設(shè)置种呐。

public class Daemon {
    public static void main(String[] args) {
        Thread thread = new Thread(new DaemonRunner());
        thread.setDaemon(true);
        thread.start();
        System.out.println(Thread.currentThread().getName() + " thread run finished");
    }

    static class DaemonRunner implements Runnable {
        @Override
        public void run() {
            try {
                SleepUtils.second(100);
            } finally {
                System.out.println("DaemonThread run finally");
            }
        }
    }
}
// 運(yùn)行結(jié)果
// main thread run finished

從例子中可以看出,當(dāng)Java虛擬機(jī)中已經(jīng)沒有非Daemon線程,虛擬機(jī)需要退出弃甥。Java虛擬機(jī)中的所有Daemon線程都需要立即 終止爽室,因此DaemonRunner立即終止,但是DaemonRunner中的finally塊并沒有執(zhí)行潘飘。

在構(gòu)建Daemon線程時(shí)肮之,不能依靠finally塊中的內(nèi)容來確保執(zhí)行關(guān)閉或清理資源
的邏輯。因此, io處理,數(shù)據(jù)庫訪問,持有資源需要及時(shí)釋放的工作不能放在Daemon線程中處理.

我們開發(fā)者很少會用到它, 它主要是用來做內(nèi)存清理,對象釋放等, 如JVM中GC操作等使用的就是Daemon進(jìn)程.

捕獲線程未處理的異常

線程中, 有兩個(gè)方法可以捕獲未處理的異常.Thread.setUncaughtExceptionHandler(UncaughtExceptionHandler)Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler).

其中 Thread.setUncaughtExceptionHandler(UncaughtExceptionHandler)非靜態(tài)方法, 因此只能處理 該線程中的未處理異常捕獲.
Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler)是靜態(tài)方法, 他可以處理進(jìn)程內(nèi),所有沒有自定義異常處理器的所有未處理異常.

對于這種異常處理, 建議只對 默認(rèn)的處理機(jī)制做增強(qiáng)處理, 而不是完全替換為自己的實(shí)現(xiàn).

應(yīng)用 : Android中獲取奔潰日志

public class LogExceptionHandler implements Thread.UncaughtExceptionHandler {
    private final Thread.UncaughtExceptionHandler mParent = Thread.getDefaultUncaughtExceptionHandler();

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        extraHandle(t, e);
        if (mParent != null)
            mParent.uncaughtException(t, e);
    }

    private static void extraHandle(Thread t, Throwable e) {
        String threadName = t.getName();
        String trace      = AlException.fullTrace(e);
        // todo 保存奔潰日志
        System.out.println("Exception in thread \"" + threadName + "\" : " + trace);
    }
}

// 在應(yīng)用入口初始化
Thread.setDefaultUncaughtExceptionHandler(new LogExceptionHandler());

線程中斷

中斷可以理解為線程的一個(gè)標(biāo)識位屬性卜录,它表示一個(gè)運(yùn)行中的線程是否被其他線程進(jìn)行 了中斷操作戈擒。中斷好比其他線程對該線程打了個(gè)招呼,其他線程通過調(diào)用該線程的interrupt() 方法對其進(jìn)行中斷操作艰毒。

理解 interrupt()方法

當(dāng)調(diào)用 interrupt()時(shí):

如果線程在處于Object#wait(), Thread#join()或者Thread#sleep(long)情況時(shí),則interrupt狀態(tài)將會被重置, 即interrupt=false,但會拋出InterruptedException

如果線程通過java.nio.channels.InterruptibleChannel阻塞在IO操作中, 則interrupt=true,且拋出java.nio.channels.ClosedByInterruptException.

如果處于非阻塞狀態(tài), 則interrupt=true,且不會拋出異常,且不會停止線程執(zhí)行.

過期的suspend()筐高、resume()和stop()

為什么官方移除了, 直接停止線程的相關(guān)操作?

不建議使用的原因主要有:以suspend()方法為例,在調(diào)用后丑瞧,線程不會釋放已經(jīng)占有的資源(比如鎖)柑土,而是占有著資源進(jìn)入睡眠狀態(tài),這樣容易引發(fā)死鎖問題绊汹。同樣稽屏,stop()方法在終結(jié)一個(gè)線程時(shí)不會保證線程的資源正常釋放,通常是沒有給予線程完成資源釋放工作的機(jī)會西乖,因此會導(dǎo)致程序可能工作在不確定狀態(tài)下狐榔。

安全退出線程

除了中斷以外坛增,通常是利用一個(gè)boolean變量來控制是否需要停止任務(wù)并終止該線程。

使用boolean變量量退出循環(huán),這個(gè)變量最好使用volatile修飾.

public class ExitThread {
    public static void main(String[] args) {
        // interrupt 的兩種情況
        Thread busyThread = new Thread(new BusyRunnable(), "busyThread");
        busyThread.start();

        Thread sleepThread = new Thread(new SleepRunnable(), "sleepThread");
        sleepThread.start();

        // boolean 標(biāo)志中斷
        TagRunnable tagRunnable = new TagRunnable();
        Thread      tagThread   = new Thread(tagRunnable, "tagThread");
        tagThread.start();

        SleepUtils.second(2);
        // 中斷
        busyThread.interrupt();
        sleepThread.interrupt();
        tagRunnable.stop();
    }

    private static class BusyRunnable implements Runnable {

        @Override
        public void run() {
            Thread t = Thread.currentThread();
            while (!t.isInterrupted()) {

            }
            System.out.println("busy thread end");
        }
    }

    private static class SleepRunnable implements Runnable {
        @Override
        public void run() {
            Thread t = Thread.currentThread();
            while (true) {
                try {
                    TimeUnit.MILLISECONDS.sleep(100);
                } catch (InterruptedException e) {
                    break;
                }
            }
            System.out.println("sleep thread end");
        }
    }

    private static class TagRunnable implements Runnable {
        private volatile boolean tag = true;

        void stop() {
            System.out.println("stop:" + Thread.currentThread().getName());
            tag = false;
        }

        @Override
        public void run() {
            System.out.println("run:" + Thread.currentThread().getName());
            while (tag) {
            }
            System.out.println("tag thread end");
        }
    }
}

yield()方法

使當(dāng)前線程從執(zhí)行狀態(tài)(運(yùn)行狀態(tài))變?yōu)榭蓤?zhí)行態(tài)(就緒狀態(tài))薄腻。cpu會從眾多的可執(zhí)行態(tài)里選擇收捣,也就是說,當(dāng)前也就是剛剛的那個(gè)線程還是有可能會被再次執(zhí)行到的庵楷,并不是說一定會執(zhí)行其他線程而該線程在下一次中不會執(zhí)行到了罢艾。

Java線程中有一個(gè)Thread.yield( )方法,很多人翻譯成線程讓步尽纽。顧名思義咐蚯,就是說當(dāng)一個(gè)線程使用了這個(gè)方法之后,它就會把自己CPU執(zhí)行的時(shí)間讓掉蜓斧,讓自己或者其它的線程重新競爭運(yùn)行仓蛆。

線程通信

共享內(nèi)存變量-線程安全通信

  • synchronized
  • volatile
  • JUC的Lock

等待/通知機(jī)制

此處講的等待通知機(jī)制,主要是指 Object.wait()/Object.notify()

方法名 描述
notify() 通知一個(gè)在對象上等待的線程,使其從wait()方法中返回.
返回的前提是 該線程獲得了對象的鎖
notifyAll() 通知所有等待在該對象上的線程
wait() 調(diào)用該放的線程進(jìn)入WAITING狀態(tài),只有等待另外線程的通知或者中斷操作才會返回,
調(diào)用wait()后,會釋放持有對象的鎖.
wait(long) 等待一段時(shí)間,如果超過long時(shí)間則直接返回

等待/通知機(jī)制是指一個(gè)線程A調(diào)用了對象O的wait()方法進(jìn)入等待狀態(tài)睁冬,而另一個(gè)線程B 調(diào)用了對象O的notify()或者notifyAll()方法挎春,線程A收到通知后從對象O的wait()方法返回,進(jìn)而 執(zhí)行后續(xù)操作豆拨。上述兩個(gè)線程通過對象O來完成交互直奋,而對象上的wait()notify/notifyAll()的 關(guān)系就如同開關(guān)信號一樣,用來完成等待方和通知方之間的交互工作施禾。

模型

等待方遵循如下原則:

  1. 獲取對象的鎖脚线。
  2. 如果條件不滿足,那么調(diào)用對象的wait()方法弥搞,被通知后仍要檢查條件邮绿。
  3. 條件滿足則執(zhí)行對應(yīng)的邏輯。
synchronized(object) {
    while(條件不滿足) {
        object.wait();
    }
    // todo 條件滿足對應(yīng)的處理
}

通知方遵循如下原則:

  1. 獲得對象的鎖攀例。
  2. 改變條件船逮。
  3. 通知所有等待在對象上的線程。
synchronized(object) { 
    // todo 改變條件
    object.notify();
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末粤铭,一起剝皮案震驚了整個(gè)濱河市挖胃,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梆惯,老刑警劉巖酱鸭,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異垛吗,居然都是意外死亡凹髓,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門怯屉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔚舀,“玉大人防泵,你說我怎么就攤上這事』雀遥” “怎么了捷泞?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長寿谴。 經(jīng)常有香客問我锁右,道長,這世上最難降的妖魔是什么讶泰? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任咏瑟,我火速辦了婚禮,結(jié)果婚禮上痪署,老公的妹妹穿的比我還像新娘码泞。我一直安慰自己,他們只是感情好狼犯,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布余寥。 她就那樣靜靜地躺著,像睡著了一般悯森。 火紅的嫁衣襯著肌膚如雪宋舷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天瓢姻,我揣著相機(jī)與錄音祝蝠,去河邊找鬼。 笑死幻碱,一個(gè)胖子當(dāng)著我的面吹牛绎狭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播褥傍,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼儡嘶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了摔桦?” 一聲冷哼從身側(cè)響起社付,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎邻耕,沒想到半個(gè)月后鸥咖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兄世,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年啼辣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片御滩。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鸥拧,死狀恐怖党远,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情富弦,我是刑警寧澤沟娱,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站腕柜,受9級特大地震影響济似,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盏缤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一砰蠢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唉铜,春花似錦台舱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至幻枉,卻和暖如春碰声,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背熬甫。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔓罚,地道東北人椿肩。 一個(gè)月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像豺谈,于是被迫代替她去往敵國和親郑象。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

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