JAVA面試匯總(二)多線程(四)

多線程內(nèi)容比較多嫩舟,今天寫完了第四篇赡矢,后邊還有五隔缀。

1. ReentrantLock 、synchronized和volatile比較

(1)ReentrantLock是一種鎖斥滤,ReentrantLock需要手動加鎖和解鎖将鸵,且解鎖的操作盡量要放在finally代碼塊中,保證線程正確釋放鎖佑颇。new ReentrantLock(true)可以實現(xiàn)公平鎖(按照等待時間越長越優(yōu)先獲得鎖權限)顶掉,如果傳入false表示非公平鎖(性能更好)。ReentrantLock可以通過lockInterruptibly()響應中斷挑胸。tryLock()可以選擇傳入時間參數(shù)一喘,表示等待指定的時間,無參則表示立即返回鎖申請的結果:true表示獲取鎖成功嗜暴,false表示獲取鎖失敗凸克。
(2)synchronized用來修飾方法或者代碼塊的,是一種鎖機制闷沥,增加了synchronized方法可以防止多線程同時執(zhí)行該方法萎战,如果是兩個實例(同一個實例可以避免)的情況下的同一個synchronized方法被執(zhí)行州藕,實際上是還能夠被同時執(zhí)行的悠砚,如果需要控制就再增加上static就可以控制了
(3)volatile用來修飾變量的,在多線程中同步變量毙籽。表示如果要使用該內(nèi)容路狮,需要直接從內(nèi)存中取值虫啥,而不能從緩存中取,避免了某些情況下的線程沖突

2. 在Java中CycliBarriar和CountdownLatch有什么區(qū)別奄妨?

(1)CountdownLatch: 一個線程(或者多個)涂籽,等待另外N個線程完成某個事情之后才能執(zhí)行。是并發(fā)包中提供的一個可用于控制多個線程同時開始某個動作的類砸抛,其采用的方法為減少計數(shù)的方式评雌,當計數(shù)減至零時位于latch.Await()后的代碼才會被執(zhí)行,CountDownLatch是減計數(shù)方式直焙,計數(shù)==0時釋放所有等待的線程景东;CountDownLatch當計數(shù)到0時,計數(shù)無法被重置奔誓。
(2)CycliBarriar字面意思回環(huán)柵欄斤吐,通過它可以實現(xiàn)讓一組線程等待至某個狀態(tài)之后再全部同時執(zhí)行。叫做回環(huán)是因為當所有等待線程都被釋放以后厨喂,CyclicBarrier可以被重用和措。 即:N個線程相互等待,任何一個線程完成之前杯聚,所有的線程都必須等待臼婆。CyclicBarrier是當await的數(shù)量到達了設置的數(shù)量的時候,才會繼續(xù)往下面執(zhí)行幌绍,CyclicBarrier計數(shù)達到指定值時颁褂,計數(shù)置為0重新開始故响。
(3)對于CountDownLatch來說,重點是那個“一個線程”,是它在等待颁独,而另外那N的線程在把“某個事情”做完之后可以繼續(xù)等待彩届,可以終止。而對于CyclicBarrier來說誓酒,重點是那N個線程樟蠕,他們之間任何一個沒有完成,所有的線程都必須等待靠柑。
(4)CountDownLatch一般用于某個線程A等待若干個其他線程執(zhí)行完任務之后寨辩,它才執(zhí)行;而CyclicBarrier一般用于一組線程互相等待至某個狀態(tài)歼冰,然后這一組線程再同時執(zhí)行靡狞;
CountDownLatch測試代碼

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class TestCountDownLatch {
    public static void main(String[] args) throws Exception {
        CountDownLatch countDownLatch = new CountDownLatch(5);
        Executor executor = Executors.newFixedThreadPool(5);
        //測試阻塞其他線程
        new Thread(new MyRunnable(countDownLatch)).start();
        //為了測試效果進行線程休眠
        Thread.sleep(1000);
        for (int i = 1; i <= 5; i++) {
            countDownLatch.countDown();
            System.out.println("第" + i + "調用countDown方法結束");
            //為了測試效果進行線程休眠
            Thread.sleep(1000);
        }
        /*
         *測試阻塞主線程
         */
        for (int i = 1; i <= 5; i++) {
            new Thread(new MyRunnable1(countDownLatch, i + "")).start();
            Thread.sleep(1000);
        }
        try {
            System.out.println("主線程阻塞");
            countDownLatch.await();
            System.out.println("主線程繼續(xù)執(zhí)行");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    static class MyRunnable implements Runnable {
        CountDownLatch countDownLatch;
        public MyRunnable(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }
        @Override
        public void run() {
            try {
                System.out.println("進入線程,即將進入阻塞狀態(tài)");
                //調用await進行線程阻塞
                countDownLatch.await();
                System.out.println("線程進行執(zhí)行...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    static class MyRunnable1 implements Runnable {
        private CountDownLatch countDownLatch;
        private String mark;
        public MyRunnable1(CountDownLatch countDownLatch, String mark) {
            super();
            this.countDownLatch = countDownLatch;
            this.mark = mark;
        }
        @Override
        public void run() {
            System.out.println(mark + "號線程開始");
            try {
                //使線程休眠隔嫡,看到更好的測試效果
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println(mark + "號線程結束");
                //調用CountDownLatch的countDown方法進行次數(shù)減1
                countDownLatch.countDown();
            }
        }
        public CountDownLatch getCountDownLatch() {
            return countDownLatch;
        }
        public void setCountDownLatch(CountDownLatch countDownLatch) {
            this.countDownLatch = countDownLatch;
        }
        public String getMark() {
            return mark;
        }
        public void setMark(String mark) {
            this.mark = mark;
        }
    }
}
//輸出
進入線程甸怕,即將進入阻塞狀態(tài)
第1調用countDown方法結束
第2調用countDown方法結束
第3調用countDown方法結束
第4調用countDown方法結束
第5調用countDown方法結束
線程進行執(zhí)行...
1號線程開始
2號線程開始
3號線程開始
4號線程開始
5號線程開始
主線程阻塞
主線程繼續(xù)執(zhí)行

CyclicBarrier測試代碼

import java.util.concurrent.*;

public class TestCyclicBarrier {
    static final Integer NUM = 5;
    public static void main(String[] args) throws InterruptedException {
        //實例CyclicBarrier對象
        CyclicBarrier cyclicBarrier = new CyclicBarrier(NUM);//實例化一個固定大小線程池
        ExecutorService executor = Executors.newFixedThreadPool(NUM);
        for (int i = 1; i <= NUM; i++) {
            //執(zhí)行線程
            executor.execute(new MyRunnale2(cyclicBarrier, i + "號"));
            //為了更好的效果,休眠一秒
            Thread.sleep(1000);
        }
        System.out.println("指令通知完成");
        //執(zhí)行完畢需要關閉腮恩,否則主線程還在這卡著不關閉
        executor.shutdown();
    }
    static class MyRunnale2 implements Runnable {
        private CyclicBarrier cyclicBarrier;
        private String mark;
        public MyRunnale2(CyclicBarrier cyclicBarrier, String mark) {
            super();
            this.cyclicBarrier = cyclicBarrier;
            this.mark = mark;
        }
        @Override
        public void run() {
            System.out.println(mark + "進入線程,線程阻塞中...");
            try {
                //barrier的await方法梢杭,在所有參與者都已經(jīng)在此barrier上調用await方法之前,將一直等待秸滴。
                cyclicBarrier.await();
                System.out.println(mark + "進入開始執(zhí)行...");
                Thread.sleep(2000);//為了看到更好的效果武契,線程阻塞兩秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println(mark + "線程阻塞結束,繼續(xù)執(zhí)行...");
        }
        public CyclicBarrier getCyclicBarrier() {
            return cyclicBarrier;
        }
        public void setCyclicBarrier(CyclicBarrier cyclicBarrier){
            this.cyclicBarrier = cyclicBarrier;
        }
    }
}
//輸出
1號進入線程,線程阻塞中...
2號進入線程,線程阻塞中...
3號進入線程,線程阻塞中...
4號進入線程,線程阻塞中...
5號進入線程,線程阻塞中...
5號進入開始執(zhí)行...
1號進入開始執(zhí)行...
2號進入開始執(zhí)行...
3號進入開始執(zhí)行...
4號進入開始執(zhí)行...
指令通知完成
3號線程阻塞結束,繼續(xù)執(zhí)行...
2號線程阻塞結束,繼續(xù)執(zhí)行...
4號線程阻塞結束,繼續(xù)執(zhí)行...
5號線程阻塞結束,繼續(xù)執(zhí)行...
1號線程阻塞結束,繼續(xù)執(zhí)行...

3. CopyOnWriteArrayList可以用于什么應用場景?

(1)ArrayList在同時遍歷和修改這個列表時缸榛,會拋出 ConcurrentModificationException吝羞。
(2)CopyOnWriteArrayList由于是copy出來的,因此不會出現(xiàn)這個錯誤内颗。
(3)寫操作的時候,需要拷貝數(shù)組敦腔,會消耗內(nèi)存均澳,如果原數(shù)組的內(nèi)容比較多的情況下,可能導致gc符衔。
(4)不能用于實時讀的場景找前,像拷貝數(shù)組、新增元素都需要時間判族,所以調用一個 set操作后躺盛,讀取到數(shù)據(jù)可能還是舊的,雖然 CopyOnWriteArrayList 能做到最終一致性,但是還是沒法滿足實時性要求。
(5)讀寫分離形帮,讀和寫分開槽惫;最終一致性周叮;使用另外開辟空間的思路,來解決并發(fā)沖突

4. Java中invokeAndWait 和 invokeLater有什么區(qū)別界斜?

這個似乎沒啥用仿耽,為啥問這個?
invokeAndWait()方法請求事件派發(fā)線程對組件進行相應更新各薇,需要等待執(zhí)行完成项贺。
invokeLater()方法是異步調用更新組件的。

5. 多線程中的忙循環(huán)是什么?

忙循環(huán)就是用戶循環(huán)讓一個線程等待峭判,不像傳統(tǒng)方法使用wait()开缎、sleep()或yield(),它們都放棄CPU控制林螃,而忙循環(huán)不會放棄CPU奕删,它就是在運行一個空循環(huán)。這么做的目的是為了保留CPU緩存治宣,在多核系統(tǒng)中急侥,一個等待線程醒來的時候可能會在另一個內(nèi)核運行,這樣會重建緩存侮邀。為了避免重建緩存和減少等待重建的時間就可以使用它了坏怪。
按照自己的理解寫了個忙循環(huán)

public class TestBusyWait {
    public static int wait = 3;
    public static void main(String[] args) throws Exception{
        new Thread(new MyRunnable()).start();
        for (int i = 0; i < 3; i++) {
            new Thread(new MyRunnable1()).start();
        }
        Thread.sleep(2000);
    }
    static class MyRunnable implements Runnable {
        public MyRunnable() {
        }
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"空循環(huán)開始");
            while (wait != 0) {
            }
            System.out.println(Thread.currentThread().getName()+"空循環(huán)完成");
        }
    }
    static class MyRunnable1 implements Runnable {
        public MyRunnable1() {
        }
        @Override
        public void run() {
            wait--;
            try {
                System.out.println(Thread.currentThread().getName()+"開始了");
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName()+"完成了");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

6. 怎么檢測一個線程是否擁有鎖?

在 java.lang.Thread 中有一個方法叫 holdsLock()绊茧,它返回 true 如果當且僅當當前線程擁有某個具體對象的鎖铝宵。

public class TestHoldsLock {
    static Object o = new Object();
    public static synchronized void method1() {
        System.out.println("before method1 Thread.holdsLock(o)=="+Thread.holdsLock(o));
        synchronized (o) {
            System.out.println("runing method1 Thread.holdsLock(o)=="+Thread.holdsLock(o));
        }
        System.out.println("after method1 Thread.holdsLock(o)=="+Thread.holdsLock(o));
    }
    public static void main(String[] args) throws InterruptedException {
        System.out.println("main Thread.holdsLock(o)=="+Thread.holdsLock(o));
        TestHoldsLock test = new TestHoldsLock();
        new Thread(new Runnable() {
            @Override
            public void run() {
                test.method1();
            }
        }).start();
    }
}
//輸出
main Thread.holdsLock(o)==false
before method1 Thread.holdsLock(o)==false
runing method1 Thread.holdsLock(o)==true
after method1 Thread.holdsLock(o)==false

7. 死鎖的四個必要條件?

(1)互斥條件:一個資源每次只能被一個進程使用华畏;
(2)請求與保持條件:一個進程因請求資源而阻塞時鹏秋,對已獲得的資源保持不放;
(3)不剝奪條件:進程已獲得的資源亡笑,在末使用完之前侣夷,不能強行剝奪;
(4)循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關系仑乌;

8. 什么是線程池百拓,如何使用?

(1)什么是線程池:java.util.concurrent.Executors提供了一個 java.util.concurrent.Executor接口的實現(xiàn)用于創(chuàng)建線程池。實際上是對多個線程統(tǒng)一管理晰甚,避免了多次創(chuàng)建銷毀操作衙传,可以控制同時執(zhí)行的最大線程數(shù),防止執(zhí)行過多式服務卡死厕九。
(2)Executors工廠類可以創(chuàng)建多種不同的線程池
(3)newSingleThreadExecutor:創(chuàng)建一個單線程的線程池蓖捶。這個線程池只有一個線程在工作,也就是相當于單線程串行執(zhí)行所有任務扁远。如果這個唯一的線程因為異常結束俊鱼,那么會有一個新的線程來替代它刻像。此線程池保證所有任務的執(zhí)行順序按照任務的提交順序執(zhí)行。
(4)newFixedThreadPool:創(chuàng)建固定大小的線程池亭引。每次提交一個任務就創(chuàng)建一個線程绎速,直到線程達到線程池的最大大小。線程池的大小一旦達到最大值就會保持不變焙蚓,如果某個線程因為執(zhí)行異常而結束纹冤,那么線程池會補充一個新線程。
(5)newCachedThreadPool:創(chuàng)建一個可緩存的線程池购公。如果線程池的大小超過了處理任務所需要的線程萌京,那么就會回收部分空閑(60秒不執(zhí)行任務)的線程,當任務數(shù)增加時宏浩,此線程池又可以智能的添加新線程來處理任務知残。此線程池不會對線程池大小做限制,線程池大小完全依賴于操作系統(tǒng)(或者說JVM)能夠創(chuàng)建的最大線程大小比庄。
(6)newScheduledThreadPool:創(chuàng)建一個大小無限的線程池求妹。此線程池支持定時以及周期性執(zhí)行任務的需求。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class SingleThreadExecutorTest {
    public static void main(String[] args) {
        //創(chuàng)建一個可重用固定線程數(shù)的線程池
        ExecutorService pool= Executors.newSingleThreadExecutor();
        //創(chuàng)建實現(xiàn)了Runnable接口對象佳窑,Thread對象當然也實現(xiàn)了Runnable接口;
        Thread t1=new MyThread();
        Thread t2=new MyThread();
        Thread t3=new MyThread();
        Thread t4=new MyThread();
        Thread t5=new MyThread();
        //將線程放到池中執(zhí)行制恍;
        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);
        pool.execute(t5);
        //關閉線程池
        pool.shutdown();

    }
    static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+" started");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" end");
        }
    }
}
//輸出
pool-1-thread-1 started
pool-1-thread-1 end
pool-1-thread-1 started
pool-1-thread-1 end
pool-1-thread-1 started
pool-1-thread-1 end
pool-1-thread-1 started
pool-1-thread-1 end
pool-1-thread-1 started
pool-1-thread-1 end
//如果修改為
ExecutorService pool= Executors.newFixedThreadPool(2);
//可以看到下面輸出同時只有2個在執(zhí)行
pool-1-thread-1 started
pool-1-thread-2 started
pool-1-thread-1 end
pool-1-thread-2 end
pool-1-thread-1 started
pool-1-thread-2 started
pool-1-thread-2 end
pool-1-thread-1 end
pool-1-thread-2 started
pool-1-thread-2 end
//ScheduledThreadPoolExecutor測試類,定時執(zhí)行任務
public class ScheduledThreadExecutorTest{
    public static void main(String[] args) {
        //下面這樣寫也可以神凑,也可以自己new
        //ScheduledExecutorService exec = Executors.newScheduledThreadPool(2);
        ScheduledThreadPoolExecutor exec =new ScheduledThreadPoolExecutor(2);
        exec.scheduleAtFixedRate(new Runnable(){//每隔一段時間執(zhí)行
            @Override
            public void run() {
                System.out.println("===================");

            }}, 1000, 5000, TimeUnit.MILLISECONDS);
        exec.scheduleAtFixedRate(new Runnable(){//每隔一段時間打印系統(tǒng)時間净神,證明兩者是互不影響的
            @Override
            public void run() {
                System.out.println(System.nanoTime());
            }}, 1000, 2000, TimeUnit.MILLISECONDS);
    }
}
//輸出,一直循環(huán)下去
===================
18116537502800
18118526972600
18120536395200
===================
18122534792700
18124535284500
===================

9. Java中interrupted 和 isInterrupted方法的區(qū)別溉委?

(1)interrupt方法用于中斷線程鹃唯。調用該方法的線程的狀態(tài)為將被置為”中斷”狀態(tài)。線程中斷僅僅是置線程的中斷狀態(tài)位瓣喊,不會停止線程坡慌。視線程的狀態(tài)為并做處理。一旦線程的中斷狀態(tài)被置為“中斷狀態(tài)”藻三,就會拋出中斷異常八匠。
(2)interrupted查詢當前線程(一定注意是當前線程)的中斷狀態(tài),并且清除原狀態(tài)趴酣。如果一個線程被中斷了,第一次調用 interrupted 則返回 true坑夯,第二次和后面的就返回 false 了岖寞。
(3)isInterrupted僅僅是查詢當前線程的中斷狀態(tài),并不清除原狀態(tài)柜蜈。

public class InterruptThreadTest extends Thread {
    @Override
    public  void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("執(zhí)行中");
            if(this.isInterrupted()){
                System.out.println("first call outside thread.interrupted(): " + this.interrupted());
                System.out.println("first call outside thread.isInterrupted(): " + this.isInterrupted());
                System.out.println("second call outside thread.interrupted(): " + this.interrupted());
                System.out.println("second call outside thread.isInterrupted(): " + this.isInterrupted());
            }
        }

    }
    public static void main(String[] args) {
        InterruptThreadTest thread = new InterruptThreadTest();
        thread.start();
        thread.interrupt();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("status: " + thread.getState());
        System.out.println("thread is alive : " + thread.isAlive() );
    }
}
//輸出
執(zhí)行中
first call outside thread.interrupted(): true
first call outside thread.isInterrupted(): false
second call outside thread.interrupted(): false
second call outside thread.isInterrupted(): false
執(zhí)行中
執(zhí)行中
執(zhí)行中
執(zhí)行中
執(zhí)行中
仗谆。指巡。。重復
status: TERMINATED
thread is alive : false

10. Java線程池中submit() 和 execute()方法有什么區(qū)別隶垮?

(1)兩個方法都可以向線程池提交任務藻雪,execute()方法的返回類型是 void,它定義在Executor 接口中狸吞。
(2) submit()方法可以返回持有計算結果的 Future 對象勉耀,它定義在ExecutorService 接口中,它擴展了 Executor 接口蹋偏,其它線程池類像ThreadPoolExecutor 和 ScheduledThreadPoolExecutor 都有這些方法便斥。
(3)excute方法會拋出異常。sumbit方法不會拋出異常威始,調用Future.get()如果有異呈嗑溃可以拋出。
(4)excute入?yún)unnable黎棠,submit入?yún)⒖梢詾镃allable(可以返回結果的)晋渺,也可以為Runnable(不能返回結果)。

public class SingleThreadExecutorTest {
    public static void main(String[] args) throws Exception{
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        Future<?> runnableFuture = executorService.submit(() -> System.out.println("run"));// submit一個Runnable任務
        Future<?> callableFuture = executorService.submit(() -> "call");// submit一個Callable任務

        executorService.execute(() -> System.out.println("test"));

        System.out.println(runnableFuture.get());// Output null
        System.out.println(callableFuture.get());// Output call
    }
}
//輸出
run
null
call
test
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脓斩,一起剝皮案震驚了整個濱河市木西,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌俭厚,老刑警劉巖户魏,帶你破解...
    沈念sama閱讀 219,110評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異挪挤,居然都是意外死亡叼丑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評論 3 395
  • 文/潘曉璐 我一進店門扛门,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鸠信,“玉大人,你說我怎么就攤上這事论寨⌒橇ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 165,474評論 0 356
  • 文/不壞的土叔 我叫張陵葬凳,是天一觀的道長绰垂。 經(jīng)常有香客問我,道長火焰,這世上最難降的妖魔是什么劲装? 我笑而不...
    開封第一講書人閱讀 58,881評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上占业,老公的妹妹穿的比我還像新娘绒怨。我一直安慰自己,他們只是感情好谦疾,可當我...
    茶點故事閱讀 67,902評論 6 392
  • 文/花漫 我一把揭開白布南蹂。 她就那樣靜靜地躺著,像睡著了一般念恍。 火紅的嫁衣襯著肌膚如雪六剥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,698評論 1 305
  • 那天樊诺,我揣著相機與錄音仗考,去河邊找鬼。 笑死词爬,一個胖子當著我的面吹牛秃嗜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播顿膨,決...
    沈念sama閱讀 40,418評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼锅锨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了恋沃?” 一聲冷哼從身側響起必搞,我...
    開封第一講書人閱讀 39,332評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎囊咏,沒想到半個月后恕洲,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,796評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡梅割,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,968評論 3 337
  • 正文 我和宋清朗相戀三年霜第,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片户辞。...
    茶點故事閱讀 40,110評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡泌类,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出底燎,到底是詐尸還是另有隱情刃榨,我是刑警寧澤,帶...
    沈念sama閱讀 35,792評論 5 346
  • 正文 年R本政府宣布双仍,位于F島的核電站枢希,受9級特大地震影響,放射性物質發(fā)生泄漏朱沃。R本人自食惡果不足惜晴玖,卻給世界環(huán)境...
    茶點故事閱讀 41,455評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧呕屎,春花似錦、人聲如沸敬察。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽莲祸。三九已至蹂安,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間锐帜,已是汗流浹背田盈。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缴阎,地道東北人允瞧。 一個月前我還...
    沈念sama閱讀 48,348評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像蛮拔,于是被迫代替她去往敵國和親述暂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,047評論 2 355

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