java并發(fā)——四種創(chuàng)建線程方式

并發(fā)概念

并發(fā)用來(lái)提高運(yùn)行在單處理器上的程序的性能谎替。

這聽(tīng)起來(lái)有些違背直覺(jué)。如果有多個(gè)CPU處理器床嫌,那么我們讓不同CPU并發(fā)處理程序一定會(huì)讓速度變快。但是我們只有一個(gè)處理器胸私,并發(fā)看起來(lái)只會(huì)增加上下文切換的開(kāi)銷(xiāo)時(shí)間厌处。真的是這樣嗎?讓這個(gè)問(wèn)題的答案反轉(zhuǎn)的是:阻塞岁疼。如果我們?cè)趫?zhí)行一段代碼中阔涉,有一處發(fā)生了阻塞,我們只能將整個(gè)程序停下來(lái)捷绒。如果我們采用并發(fā)的方式瑰排,即使這一處發(fā)生了阻塞,其他的任務(wù)還可以繼續(xù)執(zhí)行暖侨,直到程序結(jié)束椭住,最后的情況只是一處阻塞,結(jié)果還不算太壞字逗。

事實(shí)上京郑,從性能的角度看,如果沒(méi)有任務(wù)會(huì)阻塞葫掉,那么在單處理器上使用并發(fā)就沒(méi)有任何意義傻挂。 ——Bruce Eckel

實(shí)現(xiàn)并發(fā)最直接的方式就是我們的操作系統(tǒng)做的那樣,使用進(jìn)程挖息。在多任務(wù)操作系統(tǒng)中可以通過(guò)周期性將CPU從一個(gè)進(jìn)程切換到另一個(gè)進(jìn)程金拒,來(lái)實(shí)現(xiàn)同時(shí)運(yùn)行多個(gè)進(jìn)程的效果。盡管這樣會(huì)讓進(jìn)程看起來(lái)執(zhí)行的停停歇歇套腹,但是互不干擾的進(jìn)程還是非常吸引人绪抛。不同的,JAVA中使用線程來(lái)實(shí)現(xiàn)并發(fā)的概念电禀。不同的線程會(huì)共享一個(gè)進(jìn)程下的資源和I/O設(shè)備幢码,這使得如何控制訪問(wèn)的同步變成了重要的課題。

在單CPU處理器上使用并發(fā)程序在任何時(shí)刻都只是執(zhí)行一項(xiàng)工作尖飞,因此從理論上講症副,肯定可以不用任何任務(wù)而編寫(xiě)出相同的程序。但是并發(fā)提供了一個(gè)重要的組織結(jié)構(gòu)上的好處:類(lèi)似仿真等程序的設(shè)計(jì)可以極大地簡(jiǎn)化政基。最淺顯的例子贞铣,比如我們做超級(jí)馬里奧的小游戲,采用多線程來(lái)控制馬里奧和怪物的行為就比不使用方便的多沮明。如果在游戲中還有類(lèi)似菜單的按鈕辕坝,我們不可能每段代碼都去檢查這個(gè)按鈕是否被點(diǎn)擊,這個(gè)時(shí)候使用一個(gè)線程就顯得方便簡(jiǎn)潔荐健。

線程狀態(tài)

在Thread中的內(nèi)部嵌套類(lèi)State中規(guī)定酱畅,線程一共有6種狀態(tài)琳袄。

? ? ? New 新創(chuàng)建的線程

? ? ? 這里的創(chuàng)建新的線程真的是僅僅new了一個(gè)線程。創(chuàng)建新的線程纺酸,是指剛new出來(lái)的線程窖逗,這個(gè)線程沒(méi)有通過(guò)start的方法來(lái)啟動(dòng)。

? ? ? Runnable 可運(yùn)行

? ? 一旦我們調(diào)用了start方法餐蔬,這個(gè)線程開(kāi)始工作并處于可運(yùn)行狀態(tài)滑负。可運(yùn)行狀態(tài)不只包含線程運(yùn)行用含,線程中斷也被算為可運(yùn)行狀態(tài)矮慕。一個(gè)可運(yùn)行狀態(tài)的線程可能在運(yùn)行也可能沒(méi)在運(yùn)行,不要因線程在可運(yùn)行的狀態(tài)下沒(méi)運(yùn)行而急躁啄骇,很有可能這個(gè)線程的終止只

? ? 是為了讓其他的線程獲得機(jī)會(huì)痴鳄。

? ? Blocked 被阻塞


? ? 一個(gè)線程試圖去獲得一個(gè)內(nèi)部鎖時(shí),但這個(gè)內(nèi)部鎖被其他的線程持有缸夹,這個(gè)時(shí)候痪寻,為了等待去使用這個(gè)內(nèi)部鎖,這個(gè)線程將會(huì)暫時(shí)處在被阻塞的狀態(tài)虽惭。當(dāng)其他線程釋放鎖的時(shí)候橡类,這個(gè)線程獲得了內(nèi)部鎖,并且從阻塞狀態(tài)轉(zhuǎn)變?yōu)榉亲枞麪顟B(tài)芽唇。

? ? Wait 等待

? ? 一個(gè)線程等待另一個(gè)線程通知調(diào)度器一個(gè)條件(condition)顾画,這個(gè)線程自己進(jìn)入等待狀態(tài)。等待狀態(tài)和阻塞狀態(tài)很類(lèi)似匆笤,但是他們是存在本質(zhì)區(qū)別的研侣。如果另一個(gè)線程通知調(diào)度器結(jié)束,那么這個(gè)線程進(jìn)行工作炮捧,等待狀態(tài)也隨之結(jié)束庶诡。

? ? Timed waiting 計(jì)時(shí)等待


? ? 計(jì)時(shí)等待和等待是比較相似的,計(jì)時(shí)等待相比較等待多了一個(gè)超時(shí)參數(shù)咆课。調(diào)用他們導(dǎo)致線程會(huì)進(jìn)入計(jì)時(shí)等待末誓。這個(gè)狀態(tài)將一直保持到超時(shí)期滿(mǎn)或者接收到適當(dāng)?shù)耐ㄖO啾容^直接的等待书蚪,變得更加的安全喇澡。

? ? Terminated 終止


? ? 線程終止。線程run方法執(zhí)行方法體中最后一條語(yǔ)句后善炫,正常退出而自然死亡撩幽。或者箩艺,出現(xiàn)了在方法中沒(méi)有捕獲的異常窜醉,此時(shí)終止run方法意外死亡。

創(chuàng)建線程

1.Thread創(chuàng)建線程

第一種創(chuàng)建線程的方式是從Java.lang.Thread類(lèi)派生一個(gè)新的線程類(lèi)艺谆,重載它的run()方法榨惰。ExtThread類(lèi)是實(shí)現(xiàn)了Thread的一個(gè)子類(lèi),它重寫(xiě)了run方法静汤。NewThread類(lèi)是主方法琅催,創(chuàng)建了一個(gè)ExtThread的實(shí)例,并且通過(guò)調(diào)用start方法啟動(dòng)了該線程虫给,自動(dòng)調(diào)用了run方法藤抡。我們不需要手動(dòng)調(diào)用run方法,而應(yīng)該調(diào)用start方法來(lái)讓它自動(dòng)調(diào)用run方法抹估。在JAVA的API中缠黍,start是這樣定義的:

public void start( )?

使該線程開(kāi)始執(zhí)行;

Java 虛擬機(jī)調(diào)用該線程的 run 方法药蜻。

結(jié)果是兩個(gè)線程并發(fā)地運(yùn)行瓷式;當(dāng)前線程(從調(diào)用返回給 start 方法)和另一個(gè)線程(執(zhí)行其 run 方法)。

多次啟動(dòng)一個(gè)線程是非法的语泽。特別是當(dāng)線程已經(jīng)結(jié)束執(zhí)行后贸典,不能再重新啟動(dòng)。

如果我們直接調(diào)用run方法踱卵,得到的將是在main函數(shù)的主線程中調(diào)用的run方法廊驼,這樣沒(méi)有開(kāi)啟新的線程。

run方法通常會(huì)以某種形式的循環(huán)來(lái)進(jìn)行惋砂,使得任務(wù)一直運(yùn)行下去直到不再需要蔬充,所以要設(shè)定跳出循環(huán)的條件(或者直接從run方法返回)。通常run方法被寫(xiě)成無(wú)限循環(huán)的形式班利,這樣就意味著饥漫,除非某個(gè)條件使得run終止,否則他將永遠(yuǎn)運(yùn)行下去罗标。

NewThread類(lèi):

? ? package AllThread;

? ? /**

? ? *

? ? * @author QuinnNorris

? ? *

? ? *? ? ? ? 通過(guò)Thread創(chuàng)建新線程

? ? */

? ? public class NewThread {

? ? ? ? /**

? ? ? ? ? * @param args

? ? ? ? ? */

? ? ? ? ? public static void main(String[] args) {

? ? ? ? ? ? ? // TODO Auto-generated method stub

? ? ? ? ? ? ? Thread t1 = new ExtThread();

? ? ? ? ? ? ? // 創(chuàng)建一個(gè)ExtThread對(duì)象

? ? ? ? ? ? ? t1.start();

? ? ? ? ? ? ? // 調(diào)用start方法庸队,運(yùn)行新的線程,即運(yùn)行的是t1中的run方法

? ? ? ? ? }

? ? }

ExtThread類(lèi):

? ? ? package AllThread;

? ? ? /**

? ? ? *

? ? ? * @author QuinnNorris

? ? ? *

? ? ? *? ? ? ? Thread的一個(gè)實(shí)現(xiàn)類(lèi)

? ? ? */

? ? ? public class ExtThread extends Thread {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void run() {

? ? ? ? ? ? // TODO Auto-generated method stub

? ? ? ? ? ? System.out.println("new thread");

? ? ? ? ? ? }

? ? ? }

2.實(shí)現(xiàn)Runnable接口創(chuàng)建線程

在JAVA中類(lèi)僅支持單繼承闯割。這樣彻消,如果創(chuàng)建自定義線程類(lèi)的時(shí)候是通過(guò)擴(kuò)展 Thread類(lèi)的方法來(lái)實(shí)現(xiàn)的,那么這個(gè)自定義類(lèi)就不能再去擴(kuò)展其他的類(lèi)宙拉,也就無(wú)法實(shí)現(xiàn)更加復(fù)雜的功能宾尚。因此,如果自定義類(lèi)必須擴(kuò)展其他的類(lèi),那么就可以使用實(shí)現(xiàn)Runnable接口的方法來(lái)定義該類(lèi)為線程類(lèi)煌贴,這樣就可以避免Java單繼承所帶來(lái)的局限性御板。

NewRunable類(lèi):

? ? package AllThread;

? ? /**

? ? *

? ? * @author QuinnNorris

? ? *

? ? *? ? ? ? 通過(guò)Runnable接口創(chuàng)建新線程

? ? */

? ? public class NewRunable {

? ? ? ? /**

? ? ? ? ? * @param args

? ? ? ? ? */

? ? ? ? public static void main(String[] args) {

? ? ? ? ? ? ? // TODO Auto-generated method stub

? ? ? ? ? ? ? Runnable r = new ImplRunnable();

? ? ? ? ? ? // 創(chuàng)建一個(gè)Runnable實(shí)例類(lèi)的對(duì)象

? ? ? ? ? ? Thread t1 = new Thread(r);

? ? ? ? ? ? // 由r作為構(gòu)造器的參數(shù)創(chuàng)建一個(gè)Thread對(duì)象

? ? ? ? ? // 將這個(gè)Runnable子類(lèi)對(duì)象作為參數(shù)傳入Thread中

? ? ? ? ? t1.start();

? ? ? ? ? // 調(diào)用start方法,運(yùn)行新的線程牛郑,即運(yùn)行的是t1中的run方法

? ? ? ? ? }

? ? }

ImplRunnable類(lèi):

? ? package AllThread;

? ? /**

? ? *

? ? * @author QuinnNorris

? ? *

? ? *? ? ? ? Runnable的一個(gè)實(shí)現(xiàn)類(lèi)

? ? */

? ? public class ImplRunnable implements Runnable {

? ? ? ? @Override

? ? ? ? public void run() {

? ? ? ? ? ? // TODO Auto-generated method stub

? ? ? ? ? ? System.out.println("new thread");

? ? ? ? ? }

? ? ? }

多線程資源共享

我們可以利用實(shí)現(xiàn)Runnable接口的方式實(shí)現(xiàn)多線程的資源共享:把資源保存在Runnable接口中怠肋,只創(chuàng)建一份實(shí)現(xiàn)了Runnable接口的類(lèi)的實(shí)例,多個(gè)Thread對(duì)象用同一個(gè)Runnable接口實(shí)例為參數(shù)實(shí)例化淹朋。但是要注意的是笙各,資源的共享會(huì)涉及到同步的問(wèn)題,如果處理不當(dāng)础芍,那么數(shù)據(jù)的謬誤杈抢、臟數(shù)據(jù)的出現(xiàn)是必然的事情。每當(dāng)涉及到資源共享時(shí)都要小心謹(jǐn)慎仑性。而且這種資源共享的方法也不是必須的惶楼,只要我們能確保最后所有的線程都指向同一個(gè)資源,那么他的存放位置不需要被嚴(yán)格規(guī)定虏缸。

3.使用執(zhí)行器(Executor)創(chuàng)建線程池(thread pool)

使用線程池是比前兩種相對(duì)少見(jiàn)的創(chuàng)建線程做法鲫懒。從JAVA SE5開(kāi)始,java.util.concurrent包中的執(zhí)行器(Executor)將為你管理Thread對(duì)象刽辙,從而簡(jiǎn)化了并發(fā)編程窥岩。如果我們的程序需要用到很多生命周期比較短的線程,那么應(yīng)該使用線程池宰缤,線程池中包含了很多空閑線程颂翼,而且這些線程的生命周期不需要我們操心。另一個(gè)使用線程池的原因是:如果你的代碼需要大量的線程慨灭,那么最好使用一個(gè)線程池來(lái)規(guī)定總線程數(shù)的上線朦乏,防止虛擬機(jī)崩潰。這樣可以限制最大的并發(fā)數(shù)量氧骤。

靜態(tài)方法創(chuàng)建線程池實(shí)例

正如Collection類(lèi)的靜態(tài)方法都在Collections中一樣呻疹,執(zhí)行器Executor創(chuàng)建線程池的靜態(tài)方法全部在Executors類(lèi)中:

? ? ? public static ExecutorService newCachedThreadPool()

創(chuàng)建一個(gè)新的線程池。如果需要線程而線程池中無(wú)空閑線程時(shí)筹陵,創(chuàng)建一個(gè)新的線程刽锤。空閑線程會(huì)被保留60秒朦佩。

? ? ? public static ExecutorService newFixedThreadPool(int nThreads)

根據(jù)參數(shù)值創(chuàng)建一個(gè)固定數(shù)量線程的線程池并思。如果所需線程超過(guò)池中線程數(shù)則會(huì)發(fā)生等待∮锍恚空閑線程會(huì)被一直保留宋彼。

? ? ? public static ExecutorService newSingleThreadExecutor()

創(chuàng)建一個(gè)僅有一個(gè)線程的線程池,順序執(zhí)行每一個(gè)提交的任務(wù)。(和第二種方法參數(shù)為1時(shí)效果相同)

提交Runnable任務(wù)到線程池中

Executor作為一個(gè)祖先接口输涕,提供了一個(gè)也僅有一個(gè)提交線程的方法:

? ? ? void execute(Runnable command)

在Executor的子類(lèi)中音婶,有很多子類(lèi)提供了具有返回值的提交方法,返回提交的結(jié)果占贫。

? ? ? public Future<?> submit(Runnable task)

比如這種submit方法桃熄,提交一個(gè) Runnable 任務(wù)用于執(zhí)行先口,并返回一個(gè)表示該任務(wù)的 Future型奥。該 Future 的 get 方法在成功 完成時(shí)將會(huì)返回 null。調(diào)用get方法就能得到提交的結(jié)果碉京。

關(guān)閉線程池

在線程使用結(jié)束后厢汹,為了保證程序的安全,我們有必要手動(dòng)調(diào)用關(guān)閉線程池的方法:

? ? ? public void shutdown()

ThreadPool類(lèi):

? ? ? package AllThread;

? ? ? import java.util.concurrent.ExecutorService;

? ? ? import java.util.concurrent.Executors;

? ? ? /**

? ? ? *

? ? ? * @author QuinnNorris

? ? ? *

? ? ? *? ? ? ? 創(chuàng)建線程池

? ? ? */

? ? public class ThreadPool {

? ? ? /**

? ? ? ? * @param args

? ? ? ? */

? ? ? ? public static void main(String[] args) {

? ? ? ? ? ? // TODO Auto-generated method stub

? ? ? ? ? ? ExecutorService es = Executors.newFixedThreadPool(5);

? ? ? ? ? ? // 我們調(diào)用靜態(tài)方法創(chuàng)建了包含五個(gè)線程的線程池

? ? ? ? ? ? for (int i = 0; i < 5; i++)

? ? ? ? ? ? ? ? es.submit(new ImplRunnable());

? ? ? ? ? ? es.shutdown();

? ? ? ? ? ? // 在使用結(jié)束之后谐宙,一定要關(guān)閉線程池

? ? ? ? }

? ? ? }

ImplRunnable類(lèi):

? ? package AllThread;

? ? /**

? ? ? *

? ? ? * @author QuinnNorris

? ? ? *

? ? ? *? ? ? ? Runnable的一個(gè)實(shí)現(xiàn)類(lèi)

? ? ? */

? ? public class ImplRunnable implements Runnable {

? ? ? ? @Override

? ? ? ? public void run() {

? ? ? ? ? ? // TODO Auto-generated method stub

? ? ? ? ? ? System.out.println("new thread");

? ? ? ? }

? ? }

4.使用Callable與Future創(chuàng)建線程并獲取返回值

我們使用Runnable封裝了一個(gè)異步運(yùn)行的任務(wù)烫葬,我們可以把它想象成一個(gè)沒(méi)有參數(shù)和返回值的異步方法,Callable與Runnable相似凡蜻,但是Callable具有返回值搭综,可以從線程中返回?cái)?shù)據(jù)。

Callable

我們從jdk中找到了Callable<V>的源代碼划栓,去掉一些無(wú)用的部分:

? ? package java.util.concurrent;

? ? public interface Callable<V> {

? ? ? ? ? ? ? V call() throws Exception;

? ? }

可以看出Callable接口只是將run方法換成了call方法兑巾,其他并沒(méi)有太多的改動(dòng)。

Future

Future類(lèi)負(fù)責(zé)保存異步計(jì)算的結(jié)果忠荞〗瑁可以啟動(dòng)一個(gè)計(jì)算,將Future對(duì)象交給某個(gè)線程委煤,然后我們?nèi)プ銎渌氖虑樘糜停現(xiàn)uture對(duì)象的所有者在結(jié)果計(jì)算好之后就可以調(diào)用get方法獲得它。我們?cè)谏厦婢€程池的submit方法中也提到過(guò)碧绞。

V get() throws InterruptedException,ExecutionException

如有必要府框,等待計(jì)算完成,然后通過(guò)get方法獲取其結(jié)果讥邻。

FutureTask包裝器

我們雖然有了Callable和Future類(lèi)迫靖,但是我們?nèi)匀恍枰环N方法將他們結(jié)合起來(lái)使用。而且還存在的問(wèn)題是计维,Callable的出現(xiàn)替代了Runnable袜香。我們需要一種手段讓Thread類(lèi)能夠接受Callable做參數(shù)。在這里我們使用非常好用的FutureTask包裝器鲫惶。它可以將Callable轉(zhuǎn)換成Futrue和Runnable蜈首,因?yàn)樗瑫r(shí)實(shí)現(xiàn)了Runnable和Future<V>兩個(gè)接口。

CallablePool類(lèi):

? ? package AllThread;

? ? import java.util.ArrayList;

? ? import java.util.concurrent.ExecutionException;

? ? import java.util.concurrent.ExecutorService;

? ? import java.util.concurrent.Executors;

? ? import java.util.concurrent.Future;

? ? import java.util.concurrent.FutureTask;

? ? /**

? ? ? *

? ? ? * @author QuinnNorris

? ? ? *

? ? ? *? ? ? ? 用線程池實(shí)現(xiàn)Callable創(chuàng)建線程

? ? ? */

? ? public class CallablePool {

? ? ? ? /**

? ? ? ? ? * @param args

? ? ? ? ? */

? ? ? ? public static void main(String[] args) {

? ? ? ? ? ? // TODO Auto-generated method stub

? ? ? ? ? ? ExecutorService es = Executors.newFixedThreadPool(5);

? ? ? ? ? ? // 創(chuàng)建一個(gè)5個(gè)線程大小的線程池

? ? ? ? ? ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>(5);

? ? ? ? ? // 創(chuàng)建一個(gè)Future<Integer>類(lèi)型的數(shù)組

? ? ? ? ? FutureTask<Integer> ft = null;

? ? ? ? ? for (int i = 0; i < 5; i++) {

? ? ? ? ? ? ? ft = new FutureTask<Integer>(new ImplCallable(i));

? ? ? ? ? ? ? // 將Callable類(lèi)型轉(zhuǎn)化成FutureTask類(lèi)型

? ? ? ? ? ? ? es.submit(ft);

? ? ? ? ? ? ? // 提交線程

? ? ? ? ? ? ? results.add(ft);

? ? ? ? ? ? ? // 將返回的結(jié)果提交,因?yàn)镕utureTask同時(shí)也可變?yōu)镕uture類(lèi)型欢策,所以這里不需要其他類(lèi)型轉(zhuǎn)化

? ? ? ? ? }

? ? ? ? ? for (int i = 0; i < 5; i++)

? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? System.out.println(results.get(i).get());

? ? ? ? ? ? ? ? // 打印結(jié)果吆寨,發(fā)現(xiàn)數(shù)組中為0到4五個(gè)數(shù)字,成功踩寇。

? ? ? ? ? ? ? } catch (InterruptedException e) {

? ? ? ? ? ? ? ? ? // TODO Auto-generated catch block

? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? } catch (ExecutionException e) {

? ? ? ? ? ? ? ? ? // TODO Auto-generated catch block

? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? }

? ? ? ? ? }

? ? ? ? }

ImplCallable類(lèi):

? ? package AllThread;

? ? import java.util.concurrent.Callable;

? ? /**

? ? ? *

? ? ? * @author QuinnNorris

? ? ? *

? ? ? *? ? ? ? Callable的實(shí)現(xiàn)類(lèi)

? ? ? */

? ? public class ImplCallable implements Callable<Integer> {

? ? ? ? private int index;

? ? ? ? ImplCallable(int index) {

? ? ? ? ? ? ? this.index = index;

? ? ? ? }

? ? ? @Override

? ? ? public Integer call() throws Exception {

? ? ? ? ? // TODO Auto-generated method stub

? ? ? ? ? return index;

? ? ? }

? ? }

上面采用了線程池的方法來(lái)表現(xiàn)Callable和Future的使用方法啄清,如果是簡(jiǎn)單實(shí)用Thread道理也是相同的,我們需要把:

ExecutorService es = Executors.newFixedThreadPool(5);

es.submit(ft);

這兩句去掉俺孙,在for循環(huán)中替換成下面兩句辣卒。創(chuàng)建Thread實(shí)例,開(kāi)啟新的線程睛榄。

Thread th = new Thread(ft);

th.start();

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末荣茫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子场靴,更是在濱河造成了極大的恐慌啡莉,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旨剥,死亡現(xiàn)場(chǎng)離奇詭異咧欣,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)轨帜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)魄咕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人阵谚,你說(shuō)我怎么就攤上這事蚕礼。” “怎么了梢什?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵奠蹬,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我嗡午,道長(zhǎng)囤躁,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任荔睹,我火速辦了婚禮狸演,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘僻他。我一直安慰自己宵距,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布吨拗。 她就那樣靜靜地躺著满哪,像睡著了一般婿斥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上哨鸭,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天民宿,我揣著相機(jī)與錄音,去河邊找鬼像鸡。 笑死活鹰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的只估。 我是一名探鬼主播志群,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼仅乓!你這毒婦竟也來(lái)了赖舟?” 一聲冷哼從身側(cè)響起蓬戚,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤夸楣,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后子漩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體豫喧,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年幢泼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了紧显。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缕棵,死狀恐怖孵班,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情招驴,我是刑警寧澤篙程,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站别厘,受9級(jí)特大地震影響虱饿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜触趴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一氮发、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧冗懦,春花似錦爽冕、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)前塔。三九已至,卻和暖如春承冰,著一層夾襖步出監(jiān)牢的瞬間华弓,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工困乒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留寂屏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓娜搂,卻偏偏與公主長(zhǎng)得像迁霎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子百宇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

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