Java多線程(一)基礎(chǔ)知識

線程概述

線程與進程

進程

?每個運行中的任務(通常是程序)就是一個進程瓶竭。當一個程序進入內(nèi)存運行時,即變成了一個進程幸逆。每一個進程都有一定的獨立功能却嗡,進程是系統(tǒng)進行資源分配與調(diào)度的一個獨立單元。

  • 獨立性:進程是系統(tǒng)中獨立存在的實體翻诉,它可以擁有自己獨立的資源炮姨,每一個進程都有自己私有的地址空間。在沒有進程本身允許的條件下碰煌,一個用戶進程不可以直接訪問其他進程的地址空間舒岸。
  • 動態(tài)性:進程與程序的區(qū)別在于,程序只是一序列靜態(tài)指令的集合芦圾,而進程則是正在執(zhí)行中的程序蛾派,擁有自己的生命周期和各種不同的狀態(tài),是動態(tài)產(chǎn)生个少、變化以及消亡的洪乍。
  • 并發(fā)性:多個進程可以在單個處理器上并發(fā)執(zhí)行,并且不會互相影響夜焦。
  • 異步性:由于進程的相互制約典尾,使進程具有執(zhí)行的間斷性,即進程按各自獨立的糊探、 不可預知的速度向前推進钾埂。異步性會導致執(zhí)行結(jié)果的不可再現(xiàn)性,為此科平,在操作系統(tǒng)中必須配置相應的進程同步機制褥紫。
  • 結(jié)構(gòu)性:進程包含程序及其相關(guān)數(shù)據(jù)結(jié)構(gòu)。進程的實體包含進程控制塊(PCB)瞪慧,程序塊髓考、數(shù)據(jù)塊和堆棧,又稱為進程映像弃酌。

線程

?線程是進程的執(zhí)行單元氨菇,是進程的組成部分,一個進程可以擁有多個線程妓湘,一個線程必須有一個父進程查蓉。線程可以擁有自己的堆棧,自己的程序計數(shù)器以及自己的局部變量榜贴,但不擁有系統(tǒng)資源豌研,它與父進程的其它線程共享該進程的全部資源。
?一個線程可以創(chuàng)建和銷毀另一個線程,同一個進程中的多個線程之間可以并發(fā)執(zhí)行鹃共。
?線程是程序中一個單一的順序控制流程鬼佣。進程內(nèi)一個相對獨立的、可調(diào)度的執(zhí)行單元霜浴,是系統(tǒng)獨立調(diào)度和分派CPU的基本單位晶衷。在單個程序中同時運行多個線程完成不同的工作,稱為多線程阴孟。

  • 進程之間不能共享內(nèi)存房铭,但線程之間共享內(nèi)存非常容易。
  • 系統(tǒng)創(chuàng)建一個進程需要為該進程分配獨立的內(nèi)存空間温眉,并分配大量的相關(guān)資源,但創(chuàng)建線程則代價小得多翁狐,因此使用多線程來實現(xiàn)多任務比使用多進程的效率高类溢。
  • 因為線程劃分的尺度小于進程,使得多線程程序的并發(fā)性高露懒。

線程實現(xiàn)

繼承Thread類

  1. 定義Thread類的子類闯冷,并重寫run()方法,該run()方法的方法體就代表了線程要完成的任務即線程的執(zhí)行體懈词;
  2. 創(chuàng)建Thread子類的實例蛇耀,即創(chuàng)建線程對象;
  3. 調(diào)用線程對象的start()方法來啟動該線程坎弯。(注意纺涤,不是直接調(diào)用對象的run()方法,調(diào)用對象的run()方法抠忘,其實就相當于普通的方法調(diào)用撩炊,并不會創(chuàng)建線程);


    通過繼承Thread類實現(xiàn)線程.png

    線程執(zhí)行結(jié)果.png

    ?從圖中可以看到崎脉,程序創(chuàng)建了三個線程拧咳,包含一個主線程和兩個子線程。并且可以看到囚灼,線程輸出并不是連續(xù)的骆膝,這是因為線程的執(zhí)行是基于系統(tǒng)資源調(diào)度執(zhí)行的。
    ?從圖中可以看出灶体,sum變量不是連續(xù)的阅签。使用繼承Thread的方法來創(chuàng)建線程類時,多個線程之間無法共享線程類的實例變量蝎抽;因為每次創(chuàng)建線程對象時都是需要創(chuàng)建一個MyThread對象愉择,每個對象都包含自己的實例變量。

實現(xiàn)Runnable接口

  1. 定義實現(xiàn)Runnable接口的實現(xiàn)類,并重寫接口的run()方法锥涕,該run()方法的方法體就代表了線程要完成的任務即線程的執(zhí)行體衷戈;
  2. 創(chuàng)建Runnable實現(xiàn)類的實例,并以此實例作為Thread的target來創(chuàng)建Thread對象层坠,該Thread對象才是真正的線程對象殖妇;
  3. 調(diào)用Thread對象的start()方法來啟動該線程。(注意破花,不是直接調(diào)用Runnable對象的run()方法谦趣,調(diào)用Runnable對象的run()方法,其實就相當于普通的方法調(diào)用座每,并不會創(chuàng)建線程);


    通過實現(xiàn)Runnable接口實現(xiàn)線程.png

    線程執(zhí)行結(jié)果.png

    ?從圖中可以看出前鹅,sum變量時連續(xù)的。使用實現(xiàn)Runnable的方法來創(chuàng)建線程類時峭梳,多個線程之間可以共享線程類的實例變量舰绘;因為在這種方式下,程序所創(chuàng)建的Runnable對象只是線程的target葱椭,而多個線程可以共享同一個target捂寿,所以多個線程可以共享同一個線程類(線程的target類)的實例變量。

  • String getName() : 獲取當前線程的名稱孵运;
  • void run() : 線程的執(zhí)行體秦陋,線程需要完成的任務都在該方法中實現(xiàn);
  • void start() :線程對象通過調(diào)用此方法來啟動線程治笨;
  • Thread Thread.currentThread() : 返回當前正在執(zhí)行的線程驳概;

通過Callable和Future創(chuàng)建線程

  1. 創(chuàng)建Callable接口的實現(xiàn)類,并實現(xiàn)call()方法旷赖,該call()方法將作為線程執(zhí)行體抡句,并且有返回值;
  2. 創(chuàng)建Callable實現(xiàn)類的實例杠愧,使用FutureTask類來包裝Callable對象待榔,該FutureTask對象封裝了該Callable對象的call()方法的返回值;
  3. 使用FutureTask對象作為Thread對象的target創(chuàng)建并啟動新線程流济;
  4. 調(diào)用FutureTask對象的get()方法來獲得子線程執(zhí)行結(jié)束后的返回值锐锣,注意不是直接調(diào)用Callable對象的call()方法獲取返回值,Callable對象的call()方法為線程的執(zhí)行體被調(diào)用绳瘟;


    通過Callable和Futrue創(chuàng)建線程.png

    線程執(zhí)行結(jié)果.png

    ?從圖中可以看到當主線程的sum變量循環(huán)到20時雕憔,程序啟動以FutureTask對象為target的線程,然后通過調(diào)用FutureTask對象的get()方法來獲得call()方法的返回值糖声。該方法將導致程序的主進程被阻塞斤彼,直到call()方法結(jié)束并返回為止分瘦。

Callable 接口方法

  • V call() : 線程的執(zhí)行體,線程需要完成的任務都在該方法中實現(xiàn)琉苇,并帶有返回值嘲玫;

Future接口方法

  • V get() : 返回Callable對象里call()方法的返回值。調(diào)用該方法將導致程序阻塞并扇,必須等待子線程結(jié)束后才回得到返回值去团;
  • V get(long timeout, TimeUnit unit) : 返回Callable對象里call()方法的返回值。調(diào)用該方法將導致程序最多阻塞timeout和unit指定時間穷蛹,如果經(jīng)過指定時間后土陪,Callable任務依然沒有返回值,則拋出TimeoutException異常肴熏;
  • boolean cancel(boolean mayInterruptIfRunning) : 試圖取消Future里關(guān)聯(lián)的Callable任務鬼雀;
  • boolean isCancelled() : 如果在Callable任務正常完成前被取消,返回true蛙吏;
  • boolean isDone() : 如果Callable任務已完成源哩,返回true;

創(chuàng)建線程三種方式的比較

采用繼承Thread類創(chuàng)建線程的優(yōu)缺點

  • 劣勢:因為線程類已經(jīng)繼承了Thread類出刷,不能在繼承別的父類;
  • 優(yōu)勢:編寫簡單坯辩,如果訪問當前線程馁龟,則無需使用Thread.currentThrend()方法,直接使用this就可獲得當前線程漆魔;

采用實現(xiàn)Runnable坷檩,Callable接口創(chuàng)建線程的優(yōu)缺點

  • 優(yōu)勢:線程類只實現(xiàn)了Runnable接口或Callable接口,還可以繼續(xù)繼承其他類改抡;
  • 優(yōu)勢:在這種情況下矢炼,多個進程可以共享同一個target對象,所以非常適合多個相同的線程來處理同一份資源的情況阿纤,從而可以將CPU句灌、代碼和數(shù)據(jù)分開,形成清晰的模型欠拾,較好的體現(xiàn)了面向?qū)ο蟮乃枷耄?/li>
  • 劣勢:編程稍微復雜胰锌,如果需要訪問當前線程,需要使用Thread.currentThrend()方法獲让暾资昧;

線程狀態(tài)

  • 新建狀態(tài)(NEW)
  • 可運行狀態(tài)(RUNNABLE)
  • 阻塞狀態(tài)(BLOCKED)
  • 等待狀態(tài)(WAITING)
  • 計時等待狀態(tài)(TIMED_WAITING)
  • 終止狀態(tài)(TERMINATED)

新建狀態(tài)(NEW)

?當用new關(guān)鍵字創(chuàng)建一個新線程時,該線程處于新建狀態(tài)荆忍。此時他和其他的Java對象一樣格带,僅僅由JVM為其分配內(nèi)存撤缴,并初始化成員變量的值,此時線程對象沒有表現(xiàn)出線程的動態(tài)特征叽唱,程序也不會執(zhí)行線程的執(zhí)行體屈呕。

可運行狀態(tài)(RUNNABLE)

?當線程對象調(diào)用了start()方法后,線程處于runnable狀態(tài)尔觉,JVM為其創(chuàng)建方法調(diào)用棧和程序計數(shù)器凉袱。處于runnable狀態(tài)的線程,可能正在運行也可能沒有運行侦铜,這取決于JVM里線程調(diào)度器的調(diào)度专甩,當線程獲得CPU時間片時,線程執(zhí)行钉稍。
?當一個線程開始運行時涤躲,它不可能處于一直運行的狀態(tài)(除非它的線程執(zhí)行體足夠短,瞬間就執(zhí)行結(jié)束了)贡未。線程在運行過程中需要被中斷种樱,目的是讓其他線程獲得執(zhí)行的機會,線程調(diào)度的細節(jié)依賴于操作系統(tǒng)提供的服務俊卤。

阻塞與(計時)等待狀態(tài)(BLOCKED嫩挤,WAITING,TIMED_WAITING)

?當線程處于阻塞或者等待狀態(tài)時消恍,它暫時不活動岂昭。直到線程調(diào)度器重新激活它。細節(jié)取決于它是怎么達到非活動狀態(tài)的狠怨。

  • 當一個線程試圖獲取一個內(nèi)部的對象鎖(而不是java.util.concurrent庫中的鎖)约啊,而該鎖被其他線程持有時,則該線程進入阻塞狀態(tài)佣赖。當所有其他線程釋放該鎖恰矩,并且線程調(diào)度器允許本線程持有它的時候,該線程將變成非阻塞狀態(tài)憎蛤。
  • 當線程等待另一個線程通知調(diào)度器一個條件時外傅,它自己進入等待狀態(tài)。在調(diào)用Object.wait方法或Thread.join方法俩檬,或者是等待java.util.concurrent庫中的Lock或Condition時栏豺,就會出現(xiàn)這種情況。
  • 有幾個方法有一個超時參數(shù)豆胸。調(diào)用它們導致線程進入計時等待狀態(tài)奥洼。這一狀態(tài)將一直保持到超時期滿或者接收到適當?shù)耐ㄖв谐瑫r參數(shù)的方法有Thread.sleep和Object.wait晚胡、Thread.join灵奖、Lock.tryLock以及Condition.await的計時版嚼沿。

終止狀態(tài)(TERMINATED)

?線程因如下原因之一而被終止:(當然還有一種調(diào)用stop()方法,不過該方法已過時瓷患,不建議調(diào)用)

  • 因為run()方法或call()方法執(zhí)行完成骡尽,結(jié)束后線程就自然死亡。
  • 因為一個沒有捕獲的Exception或Error而意外死亡擅编。


    線程狀態(tài)轉(zhuǎn)換圖(來自一哥們).png

Thread 方法

  • void join() : 等待終止指定的線程攀细;
  • void join(long millis) : 等待指定的線程死亡或者經(jīng)過指定的毫秒數(shù);
  • Thread.State getState() : 得到這一線程的狀態(tài)爱态;NEW谭贪,RUNNABLE,BLOCKED锦担,WAITING俭识,TIMED_WAITING或者TERMINATED之一;

線程屬性

線程優(yōu)先級

?每個線程執(zhí)行都有一定的優(yōu)先級洞渔,優(yōu)先級高的獲得較多的執(zhí)行機會套媚,優(yōu)先級低的執(zhí)行機會先對較少。默認情況下磁椒,一個線程繼承它的父線程優(yōu)先級堤瘤;默認情況下,main線程具有普通優(yōu)先級浆熔,由main創(chuàng)建的線程也具普通優(yōu)先級本辐。
?Thread類提供setPriority(int newPriority),getPriority()方法來設(shè)置和獲取指定線程的優(yōu)先級蘸拔∈χ#可以將優(yōu)先級設(shè)置為MIN_PRIORITY(Thread類中定義為1)與MAX_PRIORITY(定義為10)之間的任何值环葵。默認NORM_PRIORITY被定義5调窍。
?每當線程調(diào)度器有機會選擇新線程時,他首先選擇具有高優(yōu)先級的線程张遭。但是線程優(yōu)先級是高度依賴于操作系統(tǒng)的邓萨。不同操作系統(tǒng)上的優(yōu)先級并不相同,而且也不能很好的和Java的10個優(yōu)先級對應菊卷。(例如Windows有7個優(yōu)先級缔恳。一些Java優(yōu)先級將映射到相同的操作系統(tǒng)優(yōu)先級。在Oracle為Linux提供的Java虛擬機中洁闰,線程的優(yōu)先級被忽略——所有的線程具有相同的優(yōu)先級歉甚。(來自Java核心技術(shù) 卷I))。所以應盡量避免直接為線程指定優(yōu)先級扑眉。

Thread 方法

  • void setPriority(int newPriority) : 設(shè)置線程的優(yōu)先級纸泄。優(yōu)先級必須在Thread.MIN_PRIORITY與Thread.MAX_PRIORITY之間赖钞,一般使用Thread.MIN_PRIORITY優(yōu)先級。
  • static int MIN_PRIORITY : 線程的最小優(yōu)先級聘裁,最小優(yōu)先級的值為1雪营。
  • static int NORM_PRIORITY : 線程的默認優(yōu)先級,默認優(yōu)先級的值為5衡便。
  • static int MAX_PRIORITY : 線程的最大優(yōu)先級献起,最大優(yōu)先級的值為10。
  • static native void yield() : 導致當前執(zhí)行線程處于讓步狀態(tài)镣陕。如果其他的可運行線程具有至少與此線程同樣高的優(yōu)先級谴餐,那么這些線程接下來會被調(diào)度。

守護線程

?可以通過調(diào)用setDaemon(true)將線程轉(zhuǎn)換為守護線程茁彭。守護線程的唯一用途就是為其它線程提供服務总寒。當只剩下守護線程時虛擬機就退出了,由于如果只剩下守護線程理肺,就沒必要繼續(xù)運行程序了摄闸。
?守護線程應該永遠不去訪問固有資源,如文件妹萨、數(shù)據(jù)庫年枕,因為它會在任何時候甚至在一個操作的中間發(fā)生中斷。

Thread 方法

  • void setDaemon(boolean isDaemon) : 標示該線程為守護線程或者用戶線程乎完。這一方法必須在線程啟動之前調(diào)用熏兄。
  • boolean isDaemon() : 判斷線程是否是守護線程。

常用方法

  • public synchronized void start() : 使該線程開始執(zhí)行树姨;Java 虛擬機調(diào)用該線程的 run 方法摩桶。
  • public void run() : 線程的執(zhí)行體,線程的執(zhí)行任務在該方法完成帽揪。
  • public final synchronized void setName(String name) : 設(shè)置線程的名稱硝清。
  • public final void setPriority(int newPriority) : 設(shè)置線程的優(yōu)先級。
  • public final void setDaemon(boolean on) : 將該線程設(shè)置為守護線程或者用戶線程转晰。守護線程和用戶線程的區(qū)別在于:守護線程依賴于創(chuàng)建它的線程芦拿,而用戶線程則不依賴。必須在thread.start()之前設(shè)置查邢,否則會拋出一個IllegalThreadStateException異常
  • public final void join() : 等待該線程終止蔗崎。
  • public final synchronized void join(long millis) : 等待該線程終止的時間最長為 millis 毫秒。
  • public final synchronized void join(long millis, int nanos) : 等待該線程終止扰藕,當 999999 > nanos > 500000 時缓苛,最長等待時間為 millis + 1;當 millis = 0 && nanos != 0 邓深,最長等待時間為1毫秒未桥。
  • public void interrupt() : 向線程發(fā)送中斷請求番官。線程的中斷狀態(tài)將被設(shè)置為true。如果目前該線程被一個sleep調(diào)用阻塞钢属,那么將拋出InterruptedException異常徘熔。
  • public static boolean interrupted() : 測試當前線程(即正在執(zhí)行這一命令的線程)是否被中斷。這一調(diào)用會產(chǎn)生副作用——它將當前線程的中斷狀態(tài)設(shè)置為false淆党。
  • public boolean isInterrupted() : 測試線程是否被終止酷师。這一調(diào)用不會改變線程的中斷狀態(tài)。
  • public final native boolean isAlive() : 測試線程是否處于活動狀態(tài)(線程處于正在運行或準備開始運行的狀態(tài))染乌。
  • public static native void sleep(long millis) : 在指定的毫秒數(shù)內(nèi)讓當前正在執(zhí)行的線程休眠(暫停執(zhí)行)山孔,此操作受到系統(tǒng)計時器和調(diào)度程序精度和準確性的影響。有一點要非常注意荷憋,sleep方法不會釋放鎖台颠,也就是說如果當前線程持有對某個對象的鎖,則即使調(diào)用sleep方法勒庄,其他線程也無法訪問這個對象串前。如果調(diào)用了sleep方法,必須捕獲InterruptedException異呈当危或者將該異常向上層拋出荡碾。當線程睡眠時間滿后,不一定會立即得到執(zhí)行局装,因為此時可能CPU正在執(zhí)行其他的任務坛吁。所以說調(diào)用sleep方法相當于讓線程進入阻塞狀態(tài)。
  • public static void sleep(long millis, int nanos) : 在指定的毫秒數(shù)內(nèi)讓當前正在執(zhí)行的線程休眠(暫停執(zhí)行)铐尚,當 999999 > nanos >= 500000 時拨脉,暫停時間為 millis + 1 毫秒,當 nanos != 0 && millis == 0 暫停時間為1毫秒宣增。
  • public static native void yield() : 導致當前執(zhí)行線程處于讓步狀態(tài)玫膀。如果有其他可運行的線程具有至少與此線程同樣高的優(yōu)先級,那么這些線程接下來會被調(diào)度统舀。調(diào)用yield方法會讓當前線程交出CPU權(quán)限匆骗,讓CPU去執(zhí)行其他的線程劳景。它跟sleep方法類似誉简,同樣不會釋放鎖。但是yield不能控制具體的交出CPU的時間盟广。調(diào)用yield方法并不會讓線程進入阻塞狀態(tài)闷串,而是讓線程重回就緒狀態(tài),它只需要等待重新獲取CPU執(zhí)行時間筋量,這一點是和sleep方法不一樣的烹吵。
  • public static native Thread currentThread() : 返回當前執(zhí)行線程的Thread對象碉熄。

線程面試

什么是線程?

?線程是操作系統(tǒng)能夠進行運算調(diào)度的最小單位肋拔,它被包含在進程之中锈津,是進程中的實際運作單位。

線程與進程的區(qū)別?

?進程是一個獨立的運行環(huán)境凉蜂,它可以被看作是一個程序或者一個應用琼梆。而線程是在進程中執(zhí)行的一個任務。線程是進程的子集窿吩,一個進程可以有很多線程茎杂,每條線程并行執(zhí)行不同的任務。不同的進程使用不同的內(nèi)存空間纫雁,而所有的線程共享一片相同的內(nèi)存空間煌往。別把它和棧內(nèi)存搞混,每個線程都擁有單獨的棧內(nèi)存用來存儲本地數(shù)據(jù)轧邪。

如何在Java中實現(xiàn)線程刽脖?

  • 繼承Thread類;
  • 實現(xiàn)Runnable接口忌愚;
  • 通過Callable和Future創(chuàng)建線程曾棕;

Thread 類中的start() 和 run() 方法有什么區(qū)別?

?start()方法被用來啟動新創(chuàng)建的線程菜循,而且start()內(nèi)部調(diào)用了run()方法翘地,這和直接調(diào)用run()方法的效果不一樣。當你調(diào)用run()方法的時候癌幕,只會是在原來的線程中調(diào)用衙耕,沒有新的線程啟動,start()方法才會啟動新線程勺远。

Runnable和Callable有什么不同橙喘?

?Runnable和Callable都代表那些要在不同的線程中執(zhí)行的任務。Runnable從JDK1.0開始就有了胶逢,Callable是在JDK1.5增加的厅瞎。它們的主要區(qū)別是Callable的 call() 方法可以返回值和拋出異常,而Runnable的run()方法沒有這些功能初坠。Callable可以返回裝載有計算結(jié)果的Future對象和簸。

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

?sleep()方法是線程類(Thread)的靜態(tài)方法碟刺,調(diào)用此方法會讓當前線程暫停執(zhí)行指定的時間锁保,將執(zhí)行機會(CPU)讓給其他線程,但是對象的鎖依然保持,因此休眠時間結(jié)束后會自動恢復(線程回到就緒狀態(tài))爽柒。wait()是Object類的方法吴菠,調(diào)用對象的wait()方法導致當前線程放棄對象的鎖(線程暫停執(zhí)行),進入對象的等待池浩村,只有調(diào)用對象的notify()方法(或notifyAll()方法)時才能喚醒等待池中的線程進入等鎖池做葵,如果線程重新獲得對象的鎖就可以進入就緒狀態(tài)。

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

  • sleep()方法給其他線程運行機會時不考慮線程的優(yōu)先級蜂挪,因此會給低優(yōu)先級的線程以運行的機會;yield()方法只會給相同優(yōu)先級或更高優(yōu)先級的線程以運行的機會嗓化;
  • 線程執(zhí)行sleep()方法后轉(zhuǎn)入阻塞狀態(tài)棠涮,而執(zhí)行yield()方法后轉(zhuǎn)入就緒狀態(tài);
  • sleep()方法聲明拋出InterruptedException刺覆,而yield()方法沒有聲明任何異常严肪;
  • sleep()方法比yield()方法(跟操作系統(tǒng)CPU調(diào)度相關(guān))具有更好的可移植性。

????整理文章主要為了自己日后復習用谦屑,文章中可能會引用到別的博主的文章內(nèi)容驳糯,如涉及到博主的版權(quán)問題,請博主聯(lián)系我氢橙。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酝枢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子悍手,更是在濱河造成了極大的恐慌帘睦,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坦康,死亡現(xiàn)場離奇詭異竣付,居然都是意外死亡,警方通過查閱死者的電腦和手機滞欠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門古胆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人筛璧,你說我怎么就攤上這事逸绎。” “怎么了夭谤?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵棺牧,是天一觀的道長。 經(jīng)常有香客問我沮翔,道長陨帆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任采蚀,我火速辦了婚禮疲牵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘榆鼠。我一直安慰自己纲爸,他們只是感情好,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布妆够。 她就那樣靜靜地躺著识啦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪神妹。 梳的紋絲不亂的頭發(fā)上颓哮,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機與錄音鸵荠,去河邊找鬼冕茅。 笑死,一個胖子當著我的面吹牛蛹找,可吹牛的內(nèi)容都是我干的姨伤。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼庸疾,長吁一口氣:“原來是場噩夢啊……” “哼乍楚!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起届慈,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤徒溪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后金顿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體词渤,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年串绩,在試婚紗的時候發(fā)現(xiàn)自己被綠了缺虐。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡礁凡,死狀恐怖高氮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情顷牌,我是刑警寧澤剪芍,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站窟蓝,受9級特大地震影響罪裹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一状共、第九天 我趴在偏房一處隱蔽的房頂上張望套耕。 院中可真熱鬧,春花似錦峡继、人聲如沸冯袍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽康愤。三九已至,卻和暖如春舶吗,著一層夾襖步出監(jiān)牢的瞬間征冷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工誓琼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留资盅,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓踊赠,卻偏偏與公主長得像呵扛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子筐带,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

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