線程間的協(xié)作方法(wait雨女、notify、sleep阳准、yield氛堕、join、interrupt野蝇、notifyAll)

線程的狀態(tài)

萬(wàn)事萬(wàn)物都有其自己的生命周期和狀態(tài)讼稚,一個(gè)線程從創(chuàng)建到結(jié)束被銷(xiāo)毀也有其自己的六種狀態(tài)括儒,而wait、notify锐想、sleep等等這些方法就是協(xié)助切換線程間的狀態(tài)

Oracle官方文檔提供的六種線程狀態(tài)

狀態(tài)名稱(chēng) 說(shuō)明
NEW 初始狀態(tài)帮寻,線程被創(chuàng)建,但是還沒(méi)有調(diào)用start()方法赠摇,線程還未被啟動(dòng)
RUNNABLE 運(yùn)行狀態(tài)固逗,一個(gè)線程開(kāi)始在java虛擬機(jī)中被執(zhí)行
BLOCKED 阻塞狀態(tài),線程被鎖住等待獲得對(duì)象的monitor lock,換言之就是被鎖(Synchronize)阻塞了
WAITING 等待狀態(tài)藕帜,無(wú)限期等待另一個(gè)線程執(zhí)行特定操作的線程處于此狀態(tài)烫罩。
TIMED_WAITING 超時(shí)等待狀態(tài),在指定的等待時(shí)間內(nèi)等待另一個(gè)線程執(zhí)行操作的線程處于此狀態(tài)洽故。
TERMINATED 終止?fàn)顟B(tài)贝攒,線程執(zhí)行完畢已經(jīng)退出

用一張圖可以清晰的表示上述狀態(tài)在線程中的運(yùn)行狀態(tài)切換


《JAVA并發(fā)編程的藝術(shù)》一書(shū)中的線程狀態(tài)轉(zhuǎn)換圖

線程的狀態(tài)切換的操作

建立線程后我們會(huì)根據(jù)需求對(duì)線程進(jìn)行一些操作,這些操作會(huì)改變線程的基本狀態(tài)收津,同事也成為了線程間的一種通信方式饿这,下面就主要聊聊這些方法浊伙。

  • wait()撞秋、notify()和notifyAll()

    wait方法主要是將當(dāng)前運(yùn)行的線程掛起,讓其進(jìn)入阻塞狀態(tài)嚣鄙,然后釋放它持有的同步鎖(也就是前面文章提到的monitor)吻贿,通知其他線程來(lái)獲取執(zhí)行,直到notifynotifyAll方法來(lái)喚醒哑子。

    wait也是一個(gè)多參數(shù)方法舅列,可以通過(guò)wait(long timeout)來(lái)設(shè)定線程在指定時(shí)間內(nèi)如果沒(méi)有notifynotifyAll方法的喚醒,也會(huì)自動(dòng)喚醒卧蜓,wait方法調(diào)用的也是這個(gè)方法帐要,不過(guò)傳入的參數(shù)為0L。

    在使用wait方法時(shí)弥奸,一定要在同步范圍內(nèi)榨惠,否則就會(huì)拋出IllegalMonitorStateException異常。

public class SynchronizedDemo {
    public static void main(String[] args) {
        final SynchronizedDemo test = new SynchronizedDemo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test.waitDemo();
            }
        }).start();
    }

     private void waitDemo() {
        System.out.println("Start Thread"+System.currentTimeMillis());
        try {
            wait(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("End Thread"+System.currentTimeMillis());
    }
}
運(yùn)行結(jié)果:
Start Thread1557818387416
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at com.example.javalib.SynchronizedDemo.waitDemo(SynchronizedDemo.java:24)
    at com.example.javalib.SynchronizedDemo.access$000(SynchronizedDemo.java:10)
    at com.example.javalib.SynchronizedDemo$1.run(SynchronizedDemo.java:16)
    at java.lang.Thread.run(Thread.java:745)

查看API文檔對(duì)于IllegalMonitorStateException的定義

Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

該錯(cuò)誤的大意為:線程試圖等待一個(gè)對(duì)象的監(jiān)視器或者去通知其他在等待對(duì)象監(jiān)視器的線程盛霎,但是該線程本身沒(méi)有持有指定的監(jiān)視器.主要是因?yàn)檎{(diào)用wait方法時(shí)沒(méi)有獲取到對(duì)象的monitor,獲得的途徑可以通過(guò)Synchronized關(guān)鍵字來(lái)完成赠橙,在上述代碼的方法中添加Synchronized關(guān)鍵字

private synchronized void waitDemo() {
        System.out.println("Start Thread"+System.currentTimeMillis());
        try {
            wait(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("End Thread"+System.currentTimeMillis());
    }

通過(guò)這個(gè)例子得知,wait方法的使用必須在同步的范圍內(nèi)愤炸,否則就會(huì)拋出IllegalMonitorStateException異常期揪,wait方法的作用就是阻塞當(dāng)前線程等待notify/notifyAll方法的喚醒,或等待超時(shí)后自動(dòng)喚醒规个。

wait方法通過(guò)釋放對(duì)象的monitor來(lái)掛起線程凤薛,進(jìn)入WaitSet隊(duì)列姓建, 然后后續(xù)等待鎖線程繼續(xù)來(lái)執(zhí)行,直到同一對(duì)象上調(diào)用notifynotifyAll后才可以喚醒等待線程缤苫。

notify 和 notifyAll的區(qū)別是notify方法只喚醒一個(gè)等待(對(duì)象的)線程并使該線程開(kāi)始執(zhí)行引瀑,如果有多個(gè)線程等待一個(gè)對(duì)象,那么只會(huì)隨機(jī)喚醒其中一個(gè)線程榨馁,后者則會(huì)喚醒所有等待(對(duì)象的)線程憨栽,哪個(gè)線程第一個(gè)被喚醒也是取決于操作系統(tǒng)。

負(fù)責(zé)調(diào)用方法去喚醒線程的線程也被稱(chēng)為喚醒線程翼虫,喚醒線程后不能被立刻執(zhí)行屑柔,因?yàn)閱拘丫€程還持有該對(duì)象的同步鎖,必須等待喚醒線程執(zhí)行完畢后釋放了對(duì)象的同步鎖后珍剑,等待線程才能獲取到對(duì)象的同步鎖進(jìn)而繼續(xù)執(zhí)行掸宛。

從上述中可以看到wait,notify招拙,notifyAll方法的調(diào)用去掛起喚醒線程主要是操作對(duì)象的monitor唧瘾,而monitor是所有對(duì)象的對(duì)象頭里都擁有的,所以這三個(gè)方法定義在Object類(lèi)中别凤,而不是Thread類(lèi)中

下面一個(gè)用經(jīng)典面試題:雙線程打印奇偶數(shù)來(lái)展示wait和notify的用法(代碼隨便寫(xiě)的饰序,理會(huì)意思就行)

public class Main {
    Object odd = new Object(); // 奇數(shù)條件鎖
    Object even = new Object(); // 偶數(shù)條件鎖
    private int max=200;
    private AtomicInteger status = new AtomicInteger(0); // AtomicInteger保證可見(jiàn)性,也可以用volatile

    public Main() {
    }

    public static void main(String[] args) {
        Main main = new Main();
        Thread printer1 = new Thread(main.new MyPrinter("線程1", 0));
        Thread printer2 = new Thread(main.new MyPrinter("線程2", 1));
        printer1.start();
        printer2.start();
    }
    public class MyPrinter2 implements Runnable {
        private String name;
        private int type; // 打印的類(lèi)型规哪,0:代表打印奇數(shù)求豫,1:代表打印偶數(shù)

        public MyPrinter2(String name, int type) {
            this.name = name;
            this.type = type;
        }
        @Override
        public void run() {
            ThreadBean bean = new ThreadBean();
            bean.start(name);
        }
    }
    public class MyPrinter implements Runnable {
        private String name;
        private int type; // 打印的類(lèi)型,0:代表打印奇數(shù)诉稍,1:代表打印偶數(shù)

        public MyPrinter(String name, int type) {
            this.name = name;
            this.type = type;
        }

        @Override
        public void run() {
            if (type == 0){
                while(status.get()<20){
                    if(status.get()%2==0){
                        synchronized (even){
                            try {
                                even.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }else{
                        synchronized (odd){
                            System.out.println("當(dāng)前是"+name+"輸出"+status.get());
                            status.set(status.get()+1);
                            odd.notify();
                        }
                    }
                }
            }else{
                while(status.get()<20){
                    if(status.get()%2==1){
                        synchronized (odd){
                            try {
                                odd.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }else{
                        synchronized (even){
                            System.out.println("當(dāng)前是"+name+"輸出"+status.get());
                            status.set(status.get()+1);
                            even.notify();
                        }
                    }
                }
            }
        }
    }
}

  • yield

yield是一個(gè)靜態(tài)的原生native方法蝠嘉,他的作用是讓出當(dāng)前線程的CPU分配的時(shí)間片,將其分配給和當(dāng)前線程同優(yōu)先級(jí)的線程杯巨,然后當(dāng)前線程狀態(tài)由運(yùn)行中(RUNNING)轉(zhuǎn)換為可運(yùn)行(RUNNABLE)狀態(tài)蚤告,但這個(gè)并不是等待或者阻塞狀態(tài),也不會(huì)釋放對(duì)象鎖服爷,如果在下一次競(jìng)爭(zhēng)中杜恰,又獲得了CPU時(shí)間片當(dāng)前線程依然會(huì)繼續(xù)運(yùn)行。

現(xiàn)在的操作系統(tǒng)中包含多個(gè)進(jìn)程层扶,一個(gè)進(jìn)程又包含多個(gè)線程箫章,那么這些多線程是一起執(zhí)行的嗎?就像電腦上镜会,我們可以一邊看電視一邊瀏覽網(wǎng)頁(yè)檬寂,其實(shí)并不然,看視兩邊同步進(jìn)行的戳表,但其實(shí)是cpu讓兩個(gè)線程交替執(zhí)行桶至,只不過(guò)交替執(zhí)行的速度很快昼伴,肉眼分辨不出來(lái),所以才會(huì)有同步執(zhí)行的錯(cuò)覺(jué)镣屹。同理圃郊,這里也是一樣,系統(tǒng)會(huì)分出一個(gè)個(gè)時(shí)間片女蜈,線程會(huì)被分配到屬于自己執(zhí)行的時(shí)間片持舆,當(dāng)前線程的時(shí)間片用完后會(huì)等待下次分配,線程分配的時(shí)間多少也覺(jué)得了線程使用多少處理器的資源伪窖,線程優(yōu)先級(jí)也就是覺(jué)得線程是分配多一些還是少一些處理器的資源

Java中逸寓,通過(guò)一個(gè)整型變量Priority來(lái)控制線程的優(yōu)先級(jí),范圍為1~10,通過(guò)調(diào)用setPriority(int Priority)可以設(shè)置覆山,默認(rèn)值為5竹伸。

yield一樣,sleep也調(diào)用時(shí)也會(huì)交出當(dāng)前線程的處理器資源簇宽,但是不同的是sleep交出的資源所有線程都可以去競(jìng)爭(zhēng)勋篓,yield交出的時(shí)間片資源只有和當(dāng)前線程同優(yōu)先級(jí)的線程才可以獲取到。

  • join

join方法的作用是父線程(一般是main主線程)等待子線程執(zhí)行完成后再執(zhí)行魏割,換言之就是講異步執(zhí)行的線程合并為同步的主線程,譬嚣。

wait一樣,join方法也有多個(gè)參數(shù)的方法见妒,也可以設(shè)定超時(shí)時(shí)間孤荣,join()方法調(diào)用的也是join(0L)

public class JoinDemo {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("主線程開(kāi)始"+"時(shí)間:"+System.currentTimeMillis());
        JoinDemo main = new JoinDemo();
        Thread printer1 = new Thread(main.new MyPrinter("線程1"));
        Thread printer2 = new Thread(main.new MyPrinter("線程2"));
        Thread printer3 = new Thread(main.new MyPrinter("線程3"));
        printer1.start();
        printer1.join();
        printer2.start();
        printer2.join();
        printer3.start();
        System.out.println("主線程結(jié)束"+"時(shí)間:"+System.currentTimeMillis());
    }

    public class MyPrinter implements Runnable {
        String content;

        public MyPrinter(String content) {
            this.content = content;
        }

        @Override
        public void run() {
            System.out.println("當(dāng)前線程"+content+"時(shí)間:"+System.currentTimeMillis());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
輸出結(jié)果:
主線程開(kāi)始時(shí)間:1557824674063
當(dāng)前線程線程1時(shí)間:1557824674063
當(dāng)前線程線程2時(shí)間:1557824675065
主線程結(jié)束時(shí)間:1557824676065
當(dāng)前線程線程3時(shí)間:1557824676065

從上面例子可以看到線程1和2調(diào)用了join方法后,主線程是等待兩個(gè)線程執(zhí)行完成之后才會(huì)繼續(xù)執(zhí)行

  • interrupt

interrupt的目的是為了中斷線程须揣,原來(lái)Thread.stop, Thread.suspend, Thread.resume 都有這個(gè)功能,但由于都太暴力了而被廢棄了钱豁,暴力中斷線程是一種不安全的操作耻卡,相對(duì)而言interrupt通過(guò)設(shè)置標(biāo)志位的方式就比較溫柔

interrupt基于一個(gè)線程不應(yīng)該由其他線程來(lái)強(qiáng)制中斷或停止,而是應(yīng)該由線程內(nèi)部來(lái)自行停止的思想來(lái)實(shí)現(xiàn)的牲尺,自己的事自己處理卵酪,是一種比較溫柔和安全的做法,而且中斷不活動(dòng)的線程不會(huì)產(chǎn)生任何影響谤碳。

從API文檔的中的介紹來(lái)看interrupt()的作用是中斷本線程溃卡。除非當(dāng)前線程正在中斷自身(始終允許),否則將調(diào)用此線程的checkAccess方法蜒简,但這可能導(dǎo)致拋出SecurityException瘸羡。

如果在調(diào)用Object類(lèi)的wait()join()搓茬、sleep(long)阻塞了這個(gè)線程犹赖,那么它的中斷狀態(tài)將被清除并收到InterruptedException队他。

如果在InterruptibleChannel上的I / O操作中阻塞了該線程,則該通道將被關(guān)閉峻村,線程的中斷狀態(tài)將被設(shè)置麸折,并且線程將收到ClosedByInterruptException

  • 終止阻塞線程

例如粘昨,線程通過(guò)wait()進(jìn)入阻塞狀態(tài)垢啼,此時(shí)通過(guò)interrupt()中斷該線程;調(diào)用interrupt()會(huì)立即將線程的中斷標(biāo)記設(shè)為“true”张肾,但是由于線程處于阻塞狀態(tài)膊夹,所以該“中斷標(biāo)記”會(huì)立即被清除為“false”,同時(shí)捌浩,會(huì)產(chǎn)生一個(gè)InterruptedException的異常放刨。此時(shí)將InterruptedException放在適當(dāng)?shù)奈恢眠M(jìn)行捕獲就能終止阻塞中的線程,如下代碼,將中斷的捕獲放在while(true)之外尸饺,就可以退出while循環(huán)

@Override
public void run() {
    try {
        while (true) {
            // 執(zhí)行任務(wù)...
        }
    } catch (InterruptedException ie) {  
        // 由于產(chǎn)生InterruptedException異常进统,退出while(true)循環(huán),線程終止浪听!
    }
}

但是如果需要將··InterruptedException··在··while(true)``循環(huán)體之內(nèi)的話螟碎,就需要額外的添加退出處理,通過(guò)捕獲異常后的break退出當(dāng)前循環(huán)。

@Override
public void run() {
    while (true) {
        try {
            // 執(zhí)行任務(wù)...
        } catch (InterruptedException ie) {  
            // InterruptedException在while(true)循環(huán)體內(nèi)迹栓。
            // 當(dāng)線程產(chǎn)生了InterruptedException異常時(shí)掉分,while(true)仍能繼續(xù)運(yùn)行!需要手動(dòng)退出
            break;
        }
    }
}
  • 終止運(yùn)行線程

通常克伊,我們通過(guò)“標(biāo)記”方式終止處于“運(yùn)行狀態(tài)”的線程酥郭。其中,包括“中斷標(biāo)記”和“額外添加標(biāo)記”愿吹。通過(guò)設(shè)立一個(gè)標(biāo)志來(lái)在線程運(yùn)行的時(shí)候判斷是否執(zhí)行下去不从。

@Override
public void run() {
    while (!isInterrupted()) {
    }
}

isInterruptedThread的內(nèi)部方法,可以獲取當(dāng)前線程是否中斷的標(biāo)志犁跪,當(dāng)線程處于運(yùn)行狀態(tài)時(shí)椿息,我們通過(guò)interrupt()修改線程的中斷標(biāo)志,來(lái)達(dá)到退出while循環(huán)的作用坷衍。

上述是系統(tǒng)內(nèi)部的標(biāo)志符號(hào)寝优,我們也可以自己設(shè)置一個(gè)標(biāo)志符來(lái)達(dá)到退出線程的作用

private volatile boolean isExit= false;
protected void exitThread() {
    isExit= true;
}

@Override
public void run() {
    while (isExit) {
    }
}

通過(guò)自己設(shè)置標(biāo)志符,在需要的時(shí)候直接調(diào)用exitThread就可以修改while的判斷條件枫耳,從而達(dá)到退出線程的目的乏矾。

綜合阻塞和運(yùn)行狀態(tài)下線程的終止方式,結(jié)合兩者可以使用一個(gè)通用較為安全的方法

@Override
public void run() {
    try {
        // 1. isInterrupted()保證,只要中斷標(biāo)記為true就終止線程妻熊。
        while (!isInterrupted()) {
        }
    } catch (InterruptedException ie) {  
        // 2. InterruptedException異常保證夸浅,當(dāng)InterruptedException異常產(chǎn)生時(shí),線程被終止扔役。
    }
}

最后談?wù)?interrupted()isInterrupted()帆喇。
interrupted()isInterrupted()都能夠用于檢測(cè)對(duì)象的“中斷標(biāo)記”。
區(qū)別是亿胸,interrupted()除了返回中斷標(biāo)記之外坯钦,它還會(huì)清除中斷標(biāo)記(即將中斷標(biāo)記設(shè)為false);而isInterrupted()僅僅返回中斷標(biāo)記侈玄。

  • Sleep

    最后簡(jiǎn)單說(shuō)一下sleep婉刀,這算是多線程我們最常用的方法了

    sleep是Thread的靜態(tài)native方法,它的作用是讓當(dāng)前線程按照指定的時(shí)間休眠序仙,休眠時(shí)期線程不會(huì)釋放鎖突颊,但是會(huì)讓出執(zhí)行當(dāng)前線程的cpu資源給其他線程使用,和wait較為類(lèi)似潘悼,但是也有一些不同點(diǎn)律秃。

    • sleep()是Thread的靜態(tài)內(nèi)部方法,wait()是object類(lèi)的方法
    • wait()方法必須在同步代碼塊中使用治唤,必須獲得對(duì)象鎖(monitor)棒动,sleep()方法則可以再仍和地方中使用,wait()方法會(huì)釋放當(dāng)前占有的對(duì)象鎖宾添,本身進(jìn)入waitset隊(duì)列船惨,等待被喚醒,sleep()方法只會(huì)讓出cpu資源缕陕,并不會(huì)釋放鎖
    • sleep()方法在休眠時(shí)間結(jié)束后獲得CPU分配的資源后就可以繼續(xù)執(zhí)行粱锐,wait()方法需要被notify()喚醒后還需要等待喚醒線程執(zhí)行完畢釋放鎖后,才會(huì)獲得CPU資源繼續(xù)執(zhí)行

線程的狀態(tài)轉(zhuǎn)換以及基本操作

Java 并發(fā)編程:線程間的協(xié)作

Java多線程系列--“基礎(chǔ)篇”09之 interrupt()和線程終止方式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末榄檬,一起剝皮案震驚了整個(gè)濱河市卜范,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鹿榜,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,888評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锦爵,死亡現(xiàn)場(chǎng)離奇詭異舱殿,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)险掀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)沪袭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人樟氢,你說(shuō)我怎么就攤上這事冈绊∠丽” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,386評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵死宣,是天一觀的道長(zhǎng)伟恶。 經(jīng)常有香客問(wèn)我,道長(zhǎng)毅该,這世上最難降的妖魔是什么博秫? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,726評(píng)論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮眶掌,結(jié)果婚禮上挡育,老公的妹妹穿的比我還像新娘。我一直安慰自己朴爬,他們只是感情好即寒,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著召噩,像睡著了一般母赵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蚣常,一...
    開(kāi)封第一講書(shū)人閱讀 52,337評(píng)論 1 310
  • 那天市咽,我揣著相機(jī)與錄音,去河邊找鬼抵蚊。 笑死施绎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贞绳。 我是一名探鬼主播谷醉,決...
    沈念sama閱讀 40,902評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼冈闭!你這毒婦竟也來(lái)了俱尼?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,807評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤萎攒,失蹤者是張志新(化名)和其女友劉穎遇八,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體耍休,經(jīng)...
    沈念sama閱讀 46,349評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刃永,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了羊精。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斯够。...
    茶點(diǎn)故事閱讀 40,567評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出读规,到底是詐尸還是另有隱情抓督,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評(píng)論 5 350
  • 正文 年R本政府宣布束亏,位于F島的核電站铃在,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏枪汪。R本人自食惡果不足惜涌穆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雀久。 院中可真熱鬧宿稀,春花似錦、人聲如沸赖捌。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,420評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)越庇。三九已至罩锐,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卤唉,已是汗流浹背涩惑。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,531評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桑驱,地道東北人竭恬。 一個(gè)月前我還...
    沈念sama閱讀 48,995評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像熬的,于是被迫代替她去往敵國(guó)和親痊硕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評(píng)論 2 359

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