JAVA總結(jié)(三)

Thread類的sleep()方法和對(duì)象的wait()方法都可以讓線程暫停執(zhí)行,它們有什么區(qū)別?

sleep()方法(休眠)是線程類(Thread)的靜態(tài)方法网梢,調(diào)用此方法會(huì)讓當(dāng)前線程暫停執(zhí)行指定的時(shí)間震缭,將執(zhí)行機(jī)會(huì)(CPU)讓給其他線程,但是對(duì)象的鎖依然保持战虏,因此休眠時(shí)間結(jié)束后會(huì)自動(dòng)恢復(fù)(線程回到就緒狀態(tài)拣宰,請(qǐng)參考第66題中的線程狀態(tài)轉(zhuǎn)換圖)。
wait()是Object類的方法巡社,調(diào)用對(duì)象的wait()方法導(dǎo)致當(dāng)前線程放棄對(duì)象的鎖(線程暫停執(zhí)行),進(jìn)入對(duì)象的等待池(wait pool)手趣,只有調(diào)用對(duì)象的notify()方法(或notifyAll()方法)時(shí)才能喚醒等待池中的線程進(jìn)入等鎖池(lock pool)晌该,如果線程重新獲得對(duì)象的鎖就可以進(jìn)入就緒狀態(tài)。

補(bǔ)充:可能不少人對(duì)什么是進(jìn)程回懦,什么是線程還比較模糊气笙,對(duì)于為什么需要多線程編程也不是特別理解。簡單的說:進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng)怯晕,是操作系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位潜圃;線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位舟茶,是比進(jìn)程更小的能獨(dú)立運(yùn)行的基本單位谭期。線程的劃分尺度小于進(jìn)程堵第,這使得多線程程序的并發(fā)性高;進(jìn)程在執(zhí)行時(shí)通常擁有獨(dú)立的內(nèi)存單元隧出,而線程之間可以共享內(nèi)存踏志。使用多線程的編程通常能夠帶來更好的性能和用戶體驗(yàn),但是多線程的程序?qū)τ谄渌绦蚴遣挥押玫恼偷桑驗(yàn)樗赡苷加昧烁嗟腃PU資源针余。當(dāng)然,也不是線程越多凄诞,程序的性能就越好圆雁,因?yàn)榫€程之間的調(diào)度和切換也會(huì)浪費(fèi)CPU時(shí)間。

線程的sleep()方法和yield()方法有什么區(qū)別帆谍?

① sleep()方法給其他線程運(yùn)行機(jī)會(huì)時(shí)不考慮線程的優(yōu)先級(jí)伪朽,因此會(huì)給低優(yōu)先級(jí)的線程以運(yùn)行的機(jī)會(huì);yield()方法只會(huì)給相同優(yōu)先級(jí)或更高優(yōu)先級(jí)的線程以運(yùn)行的機(jī)會(huì)汛蝙;
② 線程執(zhí)行sleep()方法后轉(zhuǎn)入阻塞(blocked)狀態(tài)烈涮,而執(zhí)行yield()方法后轉(zhuǎn)入就緒(ready)狀態(tài);
③ sleep()方法聲明拋出InterruptedException窖剑,而yield()方法沒有聲明任何異常坚洽;
④ sleep()方法比yield()方法(跟操作系統(tǒng)CPU調(diào)度相關(guān))具有更好的可移植性。

JVM中線程的狀態(tài)轉(zhuǎn)換圖

image.png

1苛吱、新建狀態(tài)(New):新創(chuàng)建了一個(gè)線程對(duì)象酪术。
2、就緒狀態(tài)(Runnable):線程對(duì)象創(chuàng)建后翠储,其他線程調(diào)用了該對(duì)象的start()方法绘雁。該狀態(tài)的線程位于“可運(yùn)行線程池”中,變得可運(yùn)行援所,只等待獲取CPU的使用權(quán)庐舟。即在就緒狀態(tài)的進(jìn)程除 CPU之外,其它的運(yùn)行所需資源都已全部獲得住拭。
3挪略、運(yùn)行狀態(tài)(Running):就緒狀態(tài)的線程獲取了CPU,執(zhí)行程序代碼滔岳。
4杠娱、阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因?yàn)槟撤N原因放棄CPU使用權(quán),暫時(shí)停止運(yùn)行谱煤。直到線程進(jìn)入就緒狀態(tài)摊求,才有機(jī)會(huì)轉(zhuǎn)到運(yùn)行狀態(tài)。
阻塞的情況分三種:

  • 等待阻塞:運(yùn)行的線程執(zhí)行wait()方法刘离,該線程會(huì)釋放占用的所有資源室叉,JVM會(huì)把該線程放入“等待池”中睹栖。進(jìn)入這個(gè)狀態(tài)后,是不能自動(dòng)喚醒的茧痕,必須依靠其他線程調(diào)用notify()或notifyAll()方法才能被喚醒野来,
  • 同步阻塞:運(yùn)行的線程在獲取對(duì)象的同步鎖時(shí),若該同步鎖被別的線程占用踪旷,則JVM會(huì)把該線程放入“鎖池”中曼氛。
  • 其他阻塞:運(yùn)行的線程執(zhí)行sleep()或join()方法,或者發(fā)出了I/O請(qǐng)求時(shí)埃脏,JVM會(huì)把該線程置為阻塞狀態(tài)搪锣。當(dāng)sleep()狀態(tài)超時(shí)、join()等待線程終止或者超時(shí)彩掐、或者I/O處理完畢時(shí),線程重新轉(zhuǎn)入就緒狀態(tài)灰追。

5堵幽、死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期弹澎。

當(dāng)一個(gè)線程進(jìn)入一個(gè)對(duì)象的synchronized方法A之后朴下,其它線程是否可進(jìn)入此對(duì)象的synchronized方法B?

不能苦蒿。其它線程只能訪問該對(duì)象的非同步方法殴胧,同步方法則不能進(jìn)入。因?yàn)榉庆o態(tài)方法上的synchronized修飾符要求執(zhí)行方法時(shí)要獲得對(duì)象的鎖佩迟,如果已經(jīng)進(jìn)入A方法說明對(duì)象鎖已經(jīng)被取走团滥,那么試圖進(jìn)入B方法的線程就只能在等鎖池(注意不是等待池哦)中等待對(duì)象的鎖。

請(qǐng)說出與線程同步以及線程調(diào)度相關(guān)的方法

  • wait():使一個(gè)線程處于等待(阻塞)狀態(tài)报强,并且釋放所持有的對(duì)象的鎖灸姊;
  • sleep():使一個(gè)正在運(yùn)行的線程處于睡眠狀態(tài),是一個(gè)靜態(tài)方法秉溉,調(diào)用此方法要處理InterruptedException異常力惯;
  • notify():喚醒一個(gè)處于等待狀態(tài)的線程,當(dāng)然在調(diào)用此方法的時(shí)候召嘶,并不能確切的喚醒某一個(gè)等待狀態(tài)的線程父晶,而是由JVM確定喚醒哪個(gè)線程,而且與優(yōu)先級(jí)無關(guān)弄跌;
  • notityAll():喚醒所有處于等待狀態(tài)的線程甲喝,該方法并不是將對(duì)象的鎖給所有線程,而是讓它們競爭碟绑,只有獲得鎖的線程才能進(jìn)入就緒狀態(tài)俺猿;

補(bǔ)充:Java 5通過Lock接口提供了顯式的鎖機(jī)制(explicit lock)茎匠,增強(qiáng)了靈活性以及對(duì)線程的協(xié)調(diào)。Lock接口中定義了加鎖(lock())和解鎖(unlock())的方法押袍,同時(shí)還提供了newCondition()方法來產(chǎn)生用于線程之間通信的Condition對(duì)象诵冒;此外,Java 5還提供了信號(hào)量機(jī)制(semaphore)谊惭,信號(hào)量可以用來限制對(duì)某個(gè)共享資源進(jìn)行訪問的線程的數(shù)量汽馋。在對(duì)資源進(jìn)行訪問之前,線程必須得到信號(hào)量的許可(調(diào)用Semaphore對(duì)象的acquire()方法)圈盔;在完成對(duì)資源的訪問后豹芯,線程必須向信號(hào)量歸還許可(調(diào)用Semaphore對(duì)象的release()方法)。

eg : 下面的例子演示了100個(gè)線程同時(shí)向一個(gè)銀行賬戶中存入1元錢驱敲,在沒有使用同步機(jī)制和使用同步機(jī)制情況下的執(zhí)行情況:
銀行賬戶類:

/**
 * 銀行賬戶
 *
 */
public class Account {
    private double balance;     // 賬戶余額
 
    /**
     * 存款
     * @param money 存入金額
     */
    public void deposit(double money) {
        double newBalance = balance + money;
        try {
            Thread.sleep(10);   // 模擬此業(yè)務(wù)需要一段處理時(shí)間
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
        balance = newBalance;
    }
 
    /**
     * 獲得賬戶余額
     */
    public double getBalance() {
        return balance;
    }
}

存錢線程類:

/**
 * 存錢線程
 *
 */
public class AddMoneyThread implements Runnable {
    private Account account;    // 存入賬戶
    private double money;       // 存入金額
 
    public AddMoneyThread(Account account, double money) {
        this.account = account;
        this.money = money;
    }
 
    @Override
    public void run() {
        account.deposit(money);
    }
 
}

測試類:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
public class Test01 {
 
    public static void main(String[] args) {
        Account account = new Account();
        ExecutorService service = Executors.newFixedThreadPool(100);
 
        for(int i = 1; i <= 100; i++) {
            service.execute(new AddMoneyThread(account, 1));
        }
 
        service.shutdown();
 
        while(!service.isTerminated()) {}
 
        System.out.println("賬戶余額: " + account.getBalance());
    }
}

在沒有同步的情況下铁蹈,執(zhí)行結(jié)果通常是顯示賬戶余額在10元以下,出現(xiàn)這種狀況的原因是众眨,當(dāng)一個(gè)線程A試圖存入1元的時(shí)候握牧,另外一個(gè)線程B也能夠進(jìn)入存款的方法中,線程B讀取到的賬戶余額仍然是線程A存入1元錢之前的賬戶余額娩梨,因此也是在原來的余額0上面做了加1元的操作沿腰,同理線程C也會(huì)做類似的事情,所以最后100個(gè)線程執(zhí)行結(jié)束時(shí)狈定,本來期望賬戶余額為100元颂龙,但實(shí)際得到的通常在10元以下(很可能是1元哦)。解決這個(gè)問題的辦法就是同步纽什,當(dāng)一個(gè)線程對(duì)銀行賬戶存錢時(shí)措嵌,需要將此賬戶鎖定,待其操作完成后才允許其他的線程進(jìn)行操作稿湿,代碼有如下幾種調(diào)整方案:
在銀行賬戶的存款(deposit)方法上同步(synchronized)關(guān)鍵字:

/**
 * 銀行賬戶
 *
 */
public class Account {
    private double balance;     // 賬戶余額
 
    /**
     * 存款
     * @param money 存入金額
     */
    public synchronized void deposit(double money) {
        double newBalance = balance + money;
        try {
            Thread.sleep(10);   // 模擬此業(yè)務(wù)需要一段處理時(shí)間
        }
        catch(InterruptedException ex) {
            ex.printStackTrace();
        }
        balance = newBalance;
    }
 
    /**
     * 獲得賬戶余額
     */
    public double getBalance() {
        return balance;
    }
}

在線程調(diào)用存款方法時(shí)對(duì)銀行賬戶進(jìn)行同步:

/**
 * 存錢線程
 *
 */
public class AddMoneyThread implements Runnable {
    private Account account;    // 存入賬戶
    private double money;       // 存入金額
 
    public AddMoneyThread(Account account, double money) {
        this.account = account;
        this.money = money;
    }
 
    @Override
    public void run() {
        synchronized (account) {
            account.deposit(money); 
        }
    }
 
}

通過Java 5顯示的鎖機(jī)制铅匹,為每個(gè)銀行賬戶創(chuàng)建一個(gè)鎖對(duì)象,在存款操作進(jìn)行加鎖和解鎖的操作:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
 
/**
 * 銀行賬戶
 *
 */
public class Account {
    private Lock accountLock = new ReentrantLock();
    private double balance; // 賬戶余額
 
    /**
     * 存款
     * 
     * @param money
     *            存入金額
     */
    public void deposit(double money) {
        accountLock.lock();
        try {
            double newBalance = balance + money;
            try {
                Thread.sleep(10); // 模擬此業(yè)務(wù)需要一段處理時(shí)間
            }
            catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            balance = newBalance;
        }
        finally {
            accountLock.unlock();
        }
    }
 
    /**
     * 獲得賬戶余額
     */
    public double getBalance() {
        return balance;
    }
}

按照上述三種方式對(duì)代碼進(jìn)行修改后饺藤,重寫執(zhí)行測試代碼Test01包斑,將看到最終的賬戶余額為100元。當(dāng)然也可以使用Semaphore或CountdownLatch來實(shí)現(xiàn)同步涕俗。

編寫多線程程序有幾種實(shí)現(xiàn)方式罗丰?

Java 5以前實(shí)現(xiàn)多線程有兩種實(shí)現(xiàn)方法:一種是繼承Thread類;另一種是實(shí)現(xiàn)Runnable接口再姑。兩種方式都要通過重寫run()方法來定義線程的行為萌抵,推薦使用后者,因?yàn)镴ava中的繼承是單繼承,一個(gè)類有一個(gè)父類绍填,如果繼承了Thread類就無法再繼承其他類了霎桅,顯然使用Runnable接口更為靈活。
補(bǔ)充:Java 5以后創(chuàng)建線程還有第三種方式:實(shí)現(xiàn)Callable接口讨永,該接口中的call方法可以在線程執(zhí)行結(jié)束時(shí)產(chǎn)生一個(gè)返回值滔驶,代碼如下所示:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
class MyTask implements Callable<Integer> {
    private int upperBounds;
 
    public MyTask(int upperBounds) {
        this.upperBounds = upperBounds;
    }
 
    @Override
    public Integer call() throws Exception {
        int sum = 0; 
        for(int i = 1; i <= upperBounds; i++) {
            sum += i;
        }
        return sum;
    }
 
}
 
class Test {
 
    public static void main(String[] args) throws Exception {
        List<Future<Integer>> list = new ArrayList<>();
        ExecutorService service = Executors.newFixedThreadPool(10);
        for(int i = 0; i < 10; i++) {
            list.add(service.submit(new MyTask((int) (Math.random() * 100))));
        }
 
        int sum = 0;
        for(Future<Integer> future : list) {
            // while(!future.isDone()) ;
            sum += future.get();
        }
 
        System.out.println(sum);
    }
}

synchronized關(guān)鍵字的用法?

synchronized關(guān)鍵字可以將對(duì)象或者方法標(biāo)記為同步卿闹,以實(shí)現(xiàn)對(duì)對(duì)象和方法的互斥訪問揭糕,可以用synchronized(對(duì)象) { … }定義同步代碼塊,或者在聲明方法時(shí)將synchronized作為方法的修飾符锻霎。

public synchronized void deposit(double money) {
    ...
}

舉例說明同步和異步

如果系統(tǒng)中存在臨界資源(資源數(shù)量少于競爭資源的線程數(shù)量的資源)著角,例如正在寫的數(shù)據(jù)以后可能被另一個(gè)線程讀到,或者正在讀的數(shù)據(jù)可能已經(jīng)被另一個(gè)線程寫過了旋恼,那么這些數(shù)據(jù)就必須進(jìn)行同步存壤艨凇(數(shù)據(jù)庫操作中的排他鎖就是最好的例子)。當(dāng)應(yīng)用程序在對(duì)象上調(diào)用了一個(gè)需要花費(fèi)很長時(shí)間來執(zhí)行的方法冰更,并且不希望讓程序等待方法的返回時(shí)锨侯,就應(yīng)該使用異步編程,在很多情況下采用異步途徑往往更有效率冬殃。事實(shí)上,所謂的同步就是指阻塞式操作叁怪,而異步就是非阻塞式操作审葬。

啟動(dòng)一個(gè)線程是調(diào)用run()還是start()方法?

啟動(dòng)一個(gè)線程是調(diào)用start()方法奕谭,使線程所代表的虛擬處理機(jī)處于可運(yùn)行狀態(tài)涣觉,這意味著它可以由JVM 調(diào)度并執(zhí)行,這并不意味著線程就會(huì)立即運(yùn)行血柳。run()方法是線程啟動(dòng)后要進(jìn)行回調(diào)(callback)的方法官册。

什么是線程池(thread pool)

在面向?qū)ο缶幊讨校瑒?chuàng)建和銷毀對(duì)象是很費(fèi)時(shí)間的难捌,因?yàn)閯?chuàng)建一個(gè)對(duì)象要獲取內(nèi)存資源或者其它更多資源膝宁。在Java中更是如此,虛擬機(jī)將試圖跟蹤每一個(gè)對(duì)象根吁,以便能夠在對(duì)象銷毀后進(jìn)行垃圾回收员淫。所以提高服務(wù)程序效率的一個(gè)手段就是盡可能減少創(chuàng)建和銷毀對(duì)象的次數(shù),特別是一些很耗資源的對(duì)象創(chuàng)建和銷毀击敌,這就是”池化資源”技術(shù)產(chǎn)生的原因介返。線程池顧名思義就是事先創(chuàng)建若干個(gè)可執(zhí)行的線程放入一個(gè)池(容器)中,需要的時(shí)候從池中獲取線程不用自行創(chuàng)建,使用完畢不需要銷毀線程而是放回池中圣蝎,從而減少創(chuàng)建和銷毀線程對(duì)象的開銷刃宵。

Java 5+中的Executor接口定義一個(gè)執(zhí)行線程的工具。它的子類型即線程池接口是ExecutorService徘公。要配置一個(gè)線程池是比較復(fù)雜的牲证,尤其是對(duì)于線程池的原理不是很清楚的情況下,因此在工具類Executors面提供了一些靜態(tài)工廠方法步淹,生成一些常用的線程池从隆,如下所示:

  • newSingleThreadExecutor:創(chuàng)建一個(gè)單線程的線程池。這個(gè)線程池只有一個(gè)線程在工作缭裆,也就是相當(dāng)于單線程串行執(zhí)行所有任務(wù)键闺。如果這個(gè)唯一的線程因?yàn)楫惓=Y(jié)束,那么會(huì)有一個(gè)新的線程來替代它澈驼。此線程池保證所有任務(wù)的執(zhí)行順序按照任務(wù)的提交順序執(zhí)行辛燥。
  • newFixedThreadPool:創(chuàng)建固定大小的線程池。每次提交一個(gè)任務(wù)就創(chuàng)建一個(gè)線程缝其,直到線程達(dá)到線程池的最大大小挎塌。線程池的大小一旦達(dá)到最大值就會(huì)保持不變,如果某個(gè)線程因?yàn)閳?zhí)行異常而結(jié)束内边,那么線程池會(huì)補(bǔ)充一個(gè)新線程榴都。
  • newCachedThreadPool:創(chuàng)建一個(gè)可緩存的線程池。如果線程池的大小超過了處理任務(wù)所需要的線程漠其,那么就會(huì)回收部分空閑(60秒不執(zhí)行任務(wù))的線程嘴高,當(dāng)任務(wù)數(shù)增加時(shí),此線程池又可以智能的添加新線程來處理任務(wù)和屎。此線程池不會(huì)對(duì)線程池大小做限制拴驮,線程池大小完全依賴于操作系統(tǒng)(或者說JVM)能夠創(chuàng)建的最大線程大小。
  • newScheduledThreadPool:創(chuàng)建一個(gè)大小無限的線程池柴信。此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求套啤。
  • newSingleThreadExecutor:創(chuàng)建一個(gè)單線程的線程池。此線程池支持定時(shí)以及周期性執(zhí)行任務(wù)的需求随常。

簡述synchronized 和java.util.concurrent.locks.Lock的異同

Lock是Java 5以后引入的新的API潜沦,和關(guān)鍵字synchronized相比主要相同點(diǎn):Lock 能完成synchronized所實(shí)現(xiàn)的所有功能;主要不同點(diǎn):Lock有比synchronized更精確的線程語義和更好的性能线罕,而且不強(qiáng)制性的要求一定要獲得鎖止潮。synchronized會(huì)自動(dòng)釋放鎖,而Lock一定要求程序員手工釋放钞楼,并且最好在finally 塊中釋放(這是釋放外部資源的最好的地方)喇闸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子燃乍,更是在濱河造成了極大的恐慌唆樊,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刻蟹,死亡現(xiàn)場離奇詭異逗旁,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)舆瘪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門片效,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人英古,你說我怎么就攤上這事淀衣。” “怎么了召调?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵膨桥,是天一觀的道長。 經(jīng)常有香客問我唠叛,道長只嚣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任艺沼,我火速辦了婚禮册舞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘障般。我一直安慰自己环础,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布剩拢。 她就那樣靜靜地躺著,像睡著了一般饶唤。 火紅的嫁衣襯著肌膚如雪徐伐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天募狂,我揣著相機(jī)與錄音办素,去河邊找鬼。 笑死祸穷,一個(gè)胖子當(dāng)著我的面吹牛性穿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播雷滚,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼需曾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起呆万,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤商源,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后谋减,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牡彻,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年出爹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庄吼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡严就,死狀恐怖总寻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盈蛮,我是刑警寧澤废菱,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站抖誉,受9級(jí)特大地震影響殊轴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜袒炉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一旁理、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧我磁,春花似錦孽文、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至郁副,卻和暖如春减牺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背存谎。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工拔疚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人既荚。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓稚失,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恰聘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子句各,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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