Android開(kāi)發(fā)十一《Android的線程和線程池》

一骚揍、主線程和子線程

1、概述

含義:線程是CPU調(diào)度的最小單元信不。
特點(diǎn):線程是一種受限的系統(tǒng)資源。即線程不可無(wú)限制的產(chǎn)生且線程的創(chuàng)建和銷毀都有一定的開(kāi)銷硫戈。
分類:
按用途可分為兩類:
  1. 主線程:一般一個(gè)進(jìn)程只有一個(gè)主線程丁逝,主要處理界面交互相關(guān)的邏輯梭姓。
  2. 子線程:除主線程之外都是子線程誉尖,主要用于執(zhí)行耗時(shí)操作。
按形態(tài)可分為三類:
  1. AsyncTask:底層封裝了線程池和Handler琢感,便于執(zhí)行后臺(tái)任務(wù)以及在主線程中進(jìn)行UI操作探熔。
  2. HandlerThread:一種具有消息循環(huán)的線程诀艰,其內(nèi)部可使用Handler。
  3. IntentService:是一種異步暗甥、會(huì)自動(dòng)停止的服務(wù),內(nèi)部采用HandlerThread虽风。

Q:如何避免頻繁創(chuàng)建和銷毀線程所帶來(lái)的系統(tǒng)開(kāi)銷辜膝?
A:采用線程池,池中會(huì)緩存一定數(shù)量的線程茎毁,進(jìn)而達(dá)到效果七蜘。Android 中的線程池來(lái)源于Java,主要通過(guò)Executor來(lái)派生特定類型的線程池扮念。

二碧库、Android中的線程形態(tài)

除了傳統(tǒng)的Thread以外嵌灰,還包含AsyncTask,HandlerThread以及IntentService迁匠,這三者底層實(shí)現(xiàn)也是線程柒瓣。

1吠架、AsyncTask

1. AsyncTask是一種輕量級(jí)的異步任務(wù)類傍药,它可以在線程池中執(zhí)行后臺(tái)任務(wù)。

在Android中實(shí)現(xiàn)異步任務(wù)機(jī)制有兩種方式:Handler和AsyncTask拣挪。

  • Handler機(jī)制存在的問(wèn)題:代碼相對(duì)臃腫俱诸;多任務(wù)同時(shí)執(zhí)行時(shí)不易精確控制線程睁搭。
  • 引入AsyncTask的優(yōu)點(diǎn):創(chuàng)建異步任務(wù)更簡(jiǎn)單园骆,直接繼承它可方便實(shí)現(xiàn)后臺(tái)異步任務(wù)的執(zhí)行和進(jìn)度的回調(diào)更新UI,而無(wú)需編寫(xiě)任務(wù)線程和Handler實(shí)例就能完成相同的任務(wù)锄码。
2. AsyncTask是抽象的泛型類,其組成成員有:

三個(gè)泛型參數(shù):
Params:表示執(zhí)行AsyncTask需要傳入的參數(shù)痛悯,可用于在后臺(tái)任務(wù)中使用灸蟆;
Progress:表示后臺(tái)任務(wù)執(zhí)行的進(jìn)度亲族;
Result: 表示后臺(tái)任務(wù)的返回結(jié)果的類型霎迫;
若沒(méi)有傳遞具體的參數(shù),這三個(gè)泛型參數(shù)都可使用void瓤帚。

public abstract class AsyncTask<Params, Progress, Result> {}
3. 五個(gè)核心方法:
  1. onPreExecute():
    運(yùn)行在:主線程
    調(diào)用時(shí)刻:在異步任務(wù)執(zhí)行之前被調(diào)用
    作用:可用于進(jìn)行一些界面上的初始化操作
  2. doInBackground(Params…params):
    運(yùn)行在:子線程
    作用:可用于處理所有的耗時(shí)任務(wù)戈次。若需要更新UI需調(diào)用 publishProgress(Progress...)方法
    注意:任務(wù)一旦完成就通過(guò)return語(yǔ)句將任務(wù)的執(zhí)行結(jié)果返回怯邪,若Result被指定為void花墩,就可不返回執(zhí)行結(jié)果
  3. onProgressUpdate(Progress…values):
    運(yùn)行在:主線程
    調(diào)用時(shí)刻:在后臺(tái)任務(wù)中調(diào)用publishProgress(Progress...)之后該方法會(huì)被調(diào)用
    作用:可利用方法中攜帶的參數(shù)如Progress來(lái)對(duì)UI進(jìn)行相應(yīng)地更新
  4. onPostExecute(Result result):
    運(yùn)行在:主線程
    調(diào)用時(shí)刻:在異步任務(wù)執(zhí)行完畢并通過(guò)return語(yǔ)句返回時(shí)被調(diào)用
    作用:可利用方法中返回的數(shù)據(jù)來(lái)進(jìn)行一些UI操作
  5. onCancelled():
    運(yùn)行在:主線程
    調(diào)用時(shí)刻:當(dāng)異步任務(wù)被取消時(shí)被調(diào)用
    作用:可用于做界面取消的更新

注意:
不要直接調(diào)用onPreExecute()冰蘑、doInBackground()、onProgressUpdate()武氓、onPostExecute)和onCancelled()方法
AsyncTask對(duì)象必須在主線程創(chuàng)建
執(zhí)行順序:onPreExecute() -> doInBackground() -> publishProgress() -> onProgressUpdate() -> onPostExecute()

4. 開(kāi)始和結(jié)束異步任務(wù)的方法:
  1. execute(Params...params)
    必須在主線程中調(diào)用
    作用:表示開(kāi)始一個(gè)異步任務(wù)
    注意:一個(gè)異步對(duì)象只能調(diào)用一次execute()方法
  2. cancel(booleanmayInterruptIfRunning)
    必須在主線程中調(diào)用
    作用:表示停止一個(gè)異步任務(wù)
5. 使用

自定義一個(gè)AsyncTask

class DownloadTask extends AsyncTask<Void, Integer, Boolean> {  
  
    @Override//初始化一個(gè)ProgressDialog  
    protected void onPreExecute() {  
        progressDialog.show();  
    }  
  
    @Override//具體的下載邏輯
    protected Boolean doInBackground(Void... params) {  
        try {  
            while (true) {  
                int downloadPercent = doDownload();  
                publishProgress(downloadPercent);  
                if (downloadPercent >= 100) {  
                    break;  
                }  
            }  
        } catch (Exception e) {  
            return false;  
        }  
        return true;  
    }  
  
    @Override//顯示當(dāng)前的下載進(jìn)度
    protected void onProgressUpdate(Integer... values) {  
        progressDialog.setMessage("當(dāng)前下載進(jìn)度:" + values[0] + "%");  
    }  
  
    @Override//提示任務(wù)的執(zhí)行結(jié)果  
    protected void onPostExecute(Boolean result) {  
        progressDialog.dismiss();  
        if (result) {  
            Toast.makeText(context, "下載成功", Toast.LENGTH_SHORT).show();  
        } else {  
            Toast.makeText(context, "下載失敗", Toast.LENGTH_SHORT).show();  
        }  
    }  
}  

開(kāi)啟任務(wù)

// 開(kāi)始任務(wù)  
DownloadTask mDownloadTask  = new DownloadTask();  
mDownloadTask .execute();  
   
// 停止任務(wù)  
mDownloadTask .cancel(true);  
6. 原理

AsyncTask封裝了Thread和Handler。

1. 內(nèi)部有一個(gè)靜態(tài)的Handler對(duì)象即InternalHandler:

作用:將執(zhí)行環(huán)境從線程池切換到主線程;通過(guò)它來(lái)發(fā)送任務(wù)執(zhí)行的進(jìn)度以及執(zhí)行結(jié)束等消息渊额。

注意:必須在主線程中創(chuàng)建

2. 內(nèi)部有兩個(gè)線程池:

SERIAL_EXECUTOR:用于任務(wù)的排隊(duì),默認(rèn)是串行的線程池
THREAD_POOL_EXECUTOR:用于真正執(zhí)行任務(wù)火惊。

3. 排隊(duì)執(zhí)行過(guò)程:

把參數(shù)Params封裝為FutureTask對(duì)象屹耐,相當(dāng)于Runnable椿猎;
調(diào)用SerialExecutor.execute()將FutureTask插入到任務(wù)隊(duì)列tasks犯眠;
若沒(méi)有正在活動(dòng)的AsyncTask任務(wù),則就會(huì)調(diào)用SerialExecutor.scheduleNext執(zhí)行下一個(gè)AsyncTask任務(wù)鸯旁。
scheduleNext方法中調(diào)用了THREAD_POOL_EXECUTOR.execute執(zhí)行任務(wù)铺罢。
執(zhí)行完畢后會(huì)繼續(xù)執(zhí)行其他任務(wù)直到所有任務(wù)都完成残炮。即默認(rèn)使用串行方式執(zhí)行任務(wù)吉殃。

注意:AsyncTask不適用于進(jìn)行特別耗時(shí)的后臺(tái)任務(wù),而是建議用線程池瓦灶。

Android1.6之前:AsyncTask串行處理任務(wù)
Android1.6~Android3.0:AsyncTask并行處理任務(wù)
Android3.0之后:AsyncTask串行處理任務(wù)贼陶,仍可以調(diào)用executeOnExecutor方法來(lái)并行執(zhí)行任務(wù)巧娱。

2禁添、HandlerThread

1. HandlerThread是一個(gè)線程類,它繼承自Thread;

與普通Thread的區(qū)別:具有消息循環(huán)的效果芹啥。原理:包含Looper

@Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }
2. HandlerThread的使用
  1. 實(shí)例化一個(gè)HandlerThread對(duì)象墓怀,參數(shù)是該線程的名稱;
  2. 通過(guò) HandlerThread.start()開(kāi)啟線程虱朵;
  3. 實(shí)例化一個(gè)Handler并傳入HandlerThread中的looper對(duì)象碴犬,使得與HandlerThread綁定官扣;
  4. 利用Handler即可執(zhí)行異步任務(wù)惕蹄;
  5. 當(dāng)不需要HandlerThread時(shí)卖陵,通過(guò)HandlerThread.quit()/quitSafely()方法來(lái)終止線程的執(zhí)行。
private HandlerThread myHandlerThread ;  
private Handler handler ;  
@Override  
protected void onCreate(Bundle savedInstanceState) {  
    super.onCreate(savedInstanceState);  
   setContentView(R.layout.activity_main);  
   //實(shí)例化HandlerThread
   myHandlerThread = new HandlerThread("myHandler") ;  
   //開(kāi)啟HandlerThread
   myHandlerThread.start();  
   //將Handler對(duì)象與HandlerThread線程綁定
   handler =new Handler(myHandlerThread.getLooper()){  
       @Override  
        publicvoid handleMessage(Message msg) {  
           super.handleMessage(msg);  
            // 這里接收Handler發(fā)來(lái)的消息棒旗,運(yùn)行在handler_thread線程中  
            //TODO...  
        }  
    };  
   
   //在主線程給Handler發(fā)送消息  
   handler.sendEmptyMessage(1) ;  
   new Thread(new Runnable() {  
       @Override  
        publicvoid run() {  
           //在子線程給Handler發(fā)送數(shù)據(jù)  
           handler.sendEmptyMessage(2) ;  
        }  
    }).start();  
}  
@Override  
protected void onDestroy() {  
   super.onDestroy();  
   //終止HandlerThread運(yùn)行
   myHandlerThread.quit() ;  
}  
3. 用途:

進(jìn)行串行異步通信
構(gòu)造IntentService

3铣揉、IntentService

1. IntentService是一個(gè)繼承自Service的抽象類
2. 優(yōu)點(diǎn)
  • 相比于線程:由于是服務(wù)逛拱,優(yōu)先級(jí)比線程高台猴,更不容易被系統(tǒng)殺死饱狂。因此較適合執(zhí)行一些高優(yōu)先級(jí)的后臺(tái)任務(wù)。
  • 相比于普通Service:可自動(dòng)創(chuàng)建子線程來(lái)執(zhí)行任務(wù)讲婚,且任務(wù)執(zhí)行完畢后自動(dòng)退出筹麸。
3. 工作原理

IntentService內(nèi)部封裝了HandlerThread和Handler。

public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    @UnsupportedAppUsage
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

    private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }

    public IntentService(String name) {
        super();
        mName = name;
    }

    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        return null;
    }

    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

工作原理
1尚骄、在IntentService.onCreate()里創(chuàng)建一個(gè)Handle對(duì)象即HandlerThread倔丈,利用其內(nèi)部的Looper會(huì)實(shí)例化一個(gè)ServiceHandler對(duì)象;
2鹉动、任務(wù)請(qǐng)求的Intent會(huì)被封裝到Message并通過(guò)ServiceHandler發(fā)送給Looper的MessageQueue泽示,最終在HandlerThread中執(zhí)行蜜氨;
3飒炎、在ServiceHandler.handleMessage()中會(huì)調(diào)用IntentService.onHandleIntent(),可在該方法中處理后臺(tái)任務(wù)的邏輯赤赊。

工作原理

三抛计、Android中的線程池

1、優(yōu)點(diǎn)

  • 重用線程池中的線程钓株,避免線程的創(chuàng)建和銷毀帶來(lái)的性能消耗橱野;
  • 有效控制線程池的最大并發(fā)數(shù)弟断,避免大量的線程之間因互相搶占系統(tǒng)資源而導(dǎo)致阻塞現(xiàn)象趴生;
  • 進(jìn)行線程管理,提供定時(shí)/循環(huán)間隔執(zhí)行等功能棚菊。

2叔汁、線程池實(shí)現(xiàn)

線程池的概念來(lái)源:Java中的Executor据块,它是一個(gè)接口。
線程池的真正實(shí)現(xiàn):ThreadPoolExecutor像屋,提供一系列參數(shù)來(lái)配置線程池己莺。

ThreadPoolExecutor構(gòu)造方法
//構(gòu)造參數(shù)
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
1. corePoolSize:核心線程數(shù)

默認(rèn)情況下篇恒,核心線程會(huì)在線程中一直存活凶杖。
當(dāng)設(shè)置ThreadPoolExecutor的allowCoreThreadTimeOut屬性為
true:表示核心線程閑置超過(guò)超時(shí)時(shí)長(zhǎng)智蝠,會(huì)被回收杈湾;
false:表示核心線程不會(huì)被回收,會(huì)在線程池中一直存活殴泰。

2. maximumPoolSize:最大線程數(shù)

當(dāng)活動(dòng)線程數(shù)達(dá)到這個(gè)數(shù)值后悍汛,后續(xù)的任務(wù)將會(huì)被阻塞至会。

3. keepAliveTime:非核心線程超時(shí)時(shí)間

超過(guò)這個(gè)時(shí)長(zhǎng)奉件,閑置的非核心線程就會(huì)被回收昆著。
當(dāng)設(shè)置ThreadPoolExecutor的allowCoreThreadTimeTout屬性為true時(shí)凑懂,keepAliveTime對(duì)核心線程同樣有效征候。

4. unit:用于指定keepAliveTime參數(shù)的時(shí)間單位

單位有:TimeUnit.MILLISECONDS祟敛、TimeUnit.SECONDS馆铁、TimeUnit.MINUTES等埠巨;

5. workQueue:任務(wù)隊(duì)列

通過(guò)線程池的execute()方法提交的Runnable對(duì)象會(huì)存儲(chǔ)在這個(gè)參數(shù)中现拒。

6. threadFactory:線程工廠印蔬,可創(chuàng)建新線程

是個(gè)接口侥猬,只有一個(gè)方法Thread newThread(Runnable r)。

7. handler:在線程池?zé)o法執(zhí)行新任務(wù)時(shí)進(jìn)行調(diào)度鹃锈。

所謂拒絕策略屎债,就是當(dāng)線程池滿了、隊(duì)列也滿了的時(shí)候盆驹,我們對(duì)任務(wù)采取的措施召娜【ィ或者丟棄秸讹、或者執(zhí)行璃诀、或者其他...
jdk自帶4種拒絕策略:

  • CallerRunsPolicy // 在調(diào)用者線程執(zhí)行
  • AbortPolicy // 直接拋出RejectedExecutionException異常
  • DiscardPolicy // 任務(wù)直接丟棄劣欢,不做任何處理
  • DiscardOldestPolicy // 丟棄隊(duì)列里最舊的那個(gè)任務(wù)裁良,再嘗試執(zhí)行當(dāng)前任務(wù)

ThreadPoolExecutor的默認(rèn)工作策略:
1价脾、若程池中的線程數(shù)量未達(dá)到核心線程數(shù)侨把,則會(huì)直接啟動(dòng)一個(gè)核心線程執(zhí)行任務(wù)。
2获枝、若線程池中的線程數(shù)量已達(dá)到或者超過(guò)核心線程數(shù)量省店,則任務(wù)會(huì)被插入到任務(wù)列表等待執(zhí)行萨西。
3旭旭、若任務(wù)無(wú)法插入到任務(wù)列表中持寄,往往由于任務(wù)列表已滿稍味,此時(shí)如果
線程數(shù)量未達(dá)到線程池最大線程數(shù)模庐,則會(huì)啟動(dòng)一個(gè)非核心線程執(zhí)行任務(wù);
4怜姿、線程數(shù)量已達(dá)到線程池規(guī)定的最大值沧卢,則拒絕執(zhí)行此任務(wù),ThreadPoolExecutor會(huì)調(diào)用RejectedExecutionHandler的rejectedExecution方法來(lái)通知調(diào)用者披诗。

3呈队、線程池分類

1. FixThreadPool:

含義:線程數(shù)量固定的線程池宪摧,所有線程都是核心線程迈喉,當(dāng)線程空閑時(shí)不會(huì)被回收挨摸。
特點(diǎn):能快速響應(yīng)外界請(qǐng)求得运。

public class Executors {
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
}
2. CachedThreadPool:

含義:線程數(shù)量不定的線程池(最大線程數(shù)為Integer.MAX_VALUE)锅移,只有非核心線程熔掺,空閑線程有超時(shí)機(jī)制,超時(shí)回收非剃。
特點(diǎn):適合于執(zhí)行大量的耗時(shí)較少的任務(wù)

public class Executors {
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
}
3. ScheduledThreadPool:

含義:核心線程數(shù)量固定置逻,非核心線程數(shù)量不定。
特點(diǎn):定時(shí)任務(wù)和固定周期的任務(wù)备绽。

public class Executors {
    public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
}
4. SingleThreadExecutor:

含義:只有一個(gè)核心線程券坞,可確保所有的任務(wù)都在同一個(gè)線程中按順序執(zhí)行。
特點(diǎn):無(wú)需處理線程同步問(wèn)題肺素。

public class Executors {
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
}

4、線程池使用

1. 創(chuàng)建自定義線程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 10000, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>());
2. 提交任務(wù)

兩種方式:execute()和submit()

executor.execute(() -> System.out.println("hello"));

Future<Long> future = executor.submit(() -> {
        System.out.println("task is executed");
        return System.currentTimeMillis();
    });
    System.out.println("task execute time is: " + future.get());
3. 關(guān)閉線程池

兩種方式:shutdown()和shutdownNow()方法

  1. shutdown()會(huì)將線程池狀態(tài)置為SHUTDOWN倍靡,不再接受新的任務(wù)猴伶,同時(shí)會(huì)等待線程池中已有的任務(wù)執(zhí)行完成再結(jié)束。
  2. shutdownNow()會(huì)將線程池狀態(tài)置為SHUTDOWN,對(duì)所有線程執(zhí)行interrupt()操作他挎,清空隊(duì)列筝尾,并將隊(duì)列中的任務(wù)返回回來(lái)。
4. 配置線程池的參數(shù)
根據(jù)任務(wù)的特性來(lái)分析:
  • 任務(wù)的性質(zhì):CPU密集型雇盖、IO密集型和混雜型
  • 任務(wù)的優(yōu)先級(jí):高中低
  • 任務(wù)執(zhí)行的時(shí)間:長(zhǎng)中短
  • 任務(wù)的依賴性:是否依賴數(shù)據(jù)庫(kù)或者其他系統(tǒng)資源
使用技巧

如果任務(wù)屬于CPU密集型忿等,那么我們可以將線程池?cái)?shù)量設(shè)置成CPU的個(gè)數(shù),以減少線程切換帶來(lái)的開(kāi)銷崔挖。如果任務(wù)屬于IO密集型贸街,我們可以將線程池?cái)?shù)量設(shè)置得更多一些,比如CPU個(gè)數(shù)*2狸相。

PS:我們可以通過(guò)Runtime.getRuntime().availableProcessors()來(lái)獲取CPU的個(gè)數(shù)薛匪。

AsyncTask中THREAD_POOL_EXECUTOR線程池配置:
核心線程數(shù) = cpu核心數(shù) + 1;
線程池最大線程數(shù) = cpu核心數(shù)*2 + 1脓鹃;
核心線程無(wú)超時(shí)機(jī)制逸尖,非核心線程在閑置時(shí)超時(shí)時(shí)間為1秒;
任務(wù)隊(duì)列的容量128瘸右;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末娇跟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子太颤,更是在濱河造成了極大的恐慌苞俘,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件龄章,死亡現(xiàn)場(chǎng)離奇詭異吃谣,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)做裙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)岗憋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人锚贱,你說(shuō)我怎么就攤上這事仔戈。” “怎么了拧廊?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵杂穷,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我卦绣,道長(zhǎng)耐量,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任滤港,我火速辦了婚禮廊蜒,結(jié)果婚禮上趴拧,老公的妹妹穿的比我還像新娘。我一直安慰自己山叮,他們只是感情好著榴,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著屁倔,像睡著了一般脑又。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锐借,一...
    開(kāi)封第一講書(shū)人閱讀 49,079評(píng)論 1 285
  • 那天问麸,我揣著相機(jī)與錄音,去河邊找鬼钞翔。 笑死严卖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的布轿。 我是一名探鬼主播哮笆,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼汰扭!你這毒婦竟也來(lái)了稠肘?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤萝毛,失蹤者是張志新(化名)和其女友劉穎项阴,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體珊泳,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鲁冯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年拷沸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了色查。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡撞芍,死狀恐怖秧了,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情序无,我是刑警寧澤验毡,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站帝嗡,受9級(jí)特大地震影響晶通,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜哟玷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一狮辽、第九天 我趴在偏房一處隱蔽的房頂上張望一也。 院中可真熱鬧,春花似錦喉脖、人聲如沸椰苟。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舆蝴。三九已至,卻和暖如春题诵,著一層夾襖步出監(jiān)牢的瞬間洁仗,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工仇轻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留京痢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓篷店,卻偏偏與公主長(zhǎng)得像祭椰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疲陕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

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