多線程基礎(chǔ)知識


基礎(chǔ)知識

同步關(guān)鍵
1猾编、對共享狀態(tài)的管理,保證對共享狀態(tài)操作的原子性蚓峦,避免靜態(tài)條件。同步機(jī)制(****synchronized****)

同步機(jī)制關(guān)鍵字:synchronized寞埠,保證了同步代碼塊中的代碼執(zhí)行順序占拍。
友情提示:在一開始就設(shè)計(jì)一個(gè)線程安全的類锄奢,比以后再將類修改為線程安全的類更容易。
編寫并發(fā)程序的編程方法先使代碼正確運(yùn)行指黎、在提高代碼的速度,提高速度這一步最好是當(dāng)性能測試結(jié)果和應(yīng)用需求顯示必須要提高性能,以及測量結(jié)果表明這個(gè)優(yōu)化在實(shí)際環(huán)境中確實(shí)能帶來性能提升時(shí)亚兄,才進(jìn)行優(yōu)化

本文中所有的提到的“狀態(tài)”一詞指的是存儲數(shù)據(jù)的意思。

要想編寫穩(wěn)定可靠的并發(fā)程序嫂侍,關(guān)鍵在于正確的使用線程和鎖儿捧,當(dāng)然這些終歸只是一種實(shí)現(xiàn)機(jī)制。編寫線程安全的核心代碼在于對狀態(tài)(數(shù)據(jù))訪問的管理挑宠,特別是對共享的(****shared****)可變的(****mutable****)狀態(tài)(數(shù)據(jù))的訪問菲盾。

共享和可變是多線程狀態(tài)管理中重要的兩個(gè)部分。其中共享指的是狀態(tài)被多個(gè)線程使用各淀,可變指的是變量的值在其生命周期內(nèi)發(fā)生變化

一個(gè)對象是否需要線程安全懒鉴,取決于這個(gè)對象是否被多線程訪問。(迄今為止碎浇,寫的所有代碼出了dao對數(shù)據(jù)庫的讀取是多線程的外临谱,業(yè)務(wù)層面幾乎都是單線程訪問對象。要改變這一狀態(tài)需要深入理解線程的使用場景奴璃。不包括框架自己的實(shí)現(xiàn))其中是否被多線程訪問指的是程序訪問對象的方式悉默,不是對象要實(shí)現(xiàn)功能的方式

當(dāng)多個(gè)線程訪問狀態(tài)變量時(shí)苟穆,如果對狀態(tài)需要執(zhí)行寫入操作抄课,就必須為這個(gè)共享狀態(tài)采取同步機(jī)制來協(xié)助這些對象對變量的訪問

當(dāng)多個(gè)線程同時(shí)訪問一個(gè)狀態(tài)變量時(shí),如果這個(gè)狀態(tài)變量沒有使用合適的同步機(jī)制雳旅。書中提供了三種修復(fù)方式:
不在線程之間共享該狀態(tài)變量跟磨。
將狀態(tài)變量修改為不可變得變量,防止多線程對狀態(tài)變量執(zhí)行寫入操作攒盈,而導(dǎo)致數(shù)據(jù)讀取異常抵拘。
在訪問該狀態(tài)變量時(shí)使用同步機(jī)制。

再往下看時(shí)型豁,我們需要問自己一個(gè)問題僵蛛。怎么區(qū)分線程安全的類和非線程安全的類“安全”的含義是什么偷遗?墩瞳??氏豌?喉酌???


線程安全最核心的概念是“正確性”泪电,如何理解正確性呢般妙??相速?正確性的定義又是什么碟渺??突诬?

在通讀書中整段話后苫拍。我覺得要定義正確性就要先知道設(shè)計(jì)這個(gè)類的初衷是什么,需要這個(gè)類完成什么事旺隙,并且輸出的結(jié)果符合設(shè)計(jì)這個(gè)類時(shí)的規(guī)范绒极,調(diào)用者不需要額外的同步、協(xié)同操作蔬捷。

書中對正確性的定義****:當(dāng)多個(gè)線程訪問這個(gè)類時(shí)垄提,不管運(yùn)行時(shí)環(huán)境采用何種調(diào)用方式或者這些線程將如何交替執(zhí)行,并且在主調(diào)代碼中不需要任何額外的同步或協(xié)同周拐,這個(gè)類都能表現(xiàn)出正確的行為铡俐,那么就稱這個(gè)類為線程安全的。

無狀態(tài)對象一定是線程安全的妥粟,在書中對無狀態(tài)對象的界定是:線程執(zhí)行過程中臨時(shí)狀態(tài)僅存儲在線程棧的局部變量中审丘,并且只能由當(dāng)前線程訪問。多個(gè)線程訪問同一個(gè)對象勾给,線程之間不能有共享狀態(tài)备恤,防止影響對方的計(jì)算結(jié)果

多線程中對共享狀態(tài)執(zhí)行寫入操作時(shí)锦秒,必須保證操作的原子性。對多線程中原子性的理解http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/

竟態(tài)條件是什么喉镰?書中定義的是當(dāng)多個(gè)線程訪問同一個(gè)共享狀態(tài)時(shí)旅择,由于執(zhí)行時(shí)序的問題導(dǎo)致返回的結(jié)果不正確。稱之為“竟態(tài)條件”

本書中“先檢查在執(zhí)行”一節(jié)的例子中侣姆,初始化數(shù)據(jù)時(shí)多線程情況下生真,如果不保證數(shù)據(jù)的原子性,返回的結(jié)果就違反了數(shù)據(jù)完整性約束捺宗,多個(gè)線程得到的結(jié)果和這個(gè)函數(shù)規(guī)定的結(jié)果不同柱蟀。我們將“先檢查后執(zhí)行”、“讀取-修改-寫入”等操作統(tǒng)一稱之為復(fù)合操作(包含了一組必須以原子方式執(zhí)行的操作以確保線程安全蚜厉。)

想要避免竟態(tài)條件的問題长已,就要在共享的變量中加入某種同步機(jī)制來確保其他線程只能在修改操作之前或者之后讀取或?qū)懭霠顟B(tài)。

應(yīng)盡可能的使用現(xiàn)有的線程安全對象來管理狀態(tài),畢竟別人專門寫的多線程更加穩(wěn)定可靠术瓮,也更容易維護(hù)和驗(yàn)證線程安全性康聂。

不變性(immutable)和只讀(read only)的區(qū)別,immutable指的是一個(gè)狀態(tài)一生只能被賦予一次值胞四,不會(huì)再改變恬汁。只讀是指一個(gè)值只能被讀取,但是值不能被直接改變辜伟,年齡就是系統(tǒng)按照每年來遞增氓侧,不是主動(dòng)修改的值。

一定要注意导狡,就算一個(gè)類中一個(gè)狀態(tài)是線程安全的烘豌,對這個(gè)狀態(tài)的操作可以當(dāng)作原子性操作廊佩。但是如果一個(gè)類多個(gè)狀態(tài),就算每個(gè)狀態(tài)都是線程安全的顽铸,也并不能能保證在多線程情況下對多個(gè)狀態(tài)操作的原子性谓松,導(dǎo)致破換了數(shù)據(jù)的完整性鬼譬。

同步代碼塊包括兩個(gè)部分:一個(gè)做為鎖的對象引用优质、一個(gè)做為由這個(gè)鎖保護(hù)的代碼塊


死鎖是什么:當(dāng)線程 1 獲得鎖 a 等待獲得鎖 b 军洼,同時(shí)線程 2 獲得鎖 b 等待獲得鎖 a 時(shí)匕争,就會(huì)出現(xiàn)死鎖的情況甘桑,解決死鎖的方式 ****http://wiki.jikexueyuan.com/project/java-concurrent/deadlock-prevention.html


嵌套管程死鎖:當(dāng)線程 1 持有鎖 a歹叮,同時(shí)等待從線程 2 發(fā)來信號盗胀,但線程 2 需要鎖 a 來發(fā)送信號給線程 1 票灰。此時(shí)就導(dǎo)致了嵌套管程死鎖的發(fā)生 ****http://wiki.jikexueyuan.com/project/java-concurrent/nested-monitor-lockout.html


死鎖和嵌套管程的區(qū)別:
死鎖:死鎖是雙方都在等待對方釋放鎖屑迂。
嵌套管程:當(dāng)線程 1 持有鎖 a惹盼,同時(shí)等待從線程 2 發(fā)來信號惫确,但線程 2 需要鎖 a 來發(fā)送信號給線程 1 改化。由于需要鎖 a 才能發(fā)送信號給線程 1 ,但鎖 a 又一直被等待信號的線程占用導(dǎo)致嵌套管程死鎖揍鸟。


單線程重入鎖的概念:當(dāng)一個(gè)程序在運(yùn)行的時(shí)候句旱,執(zhí)行線程可以再次進(jìn)入并執(zhí)行當(dāng)前程序谈撒,仍然符合設(shè)計(jì)預(yù)期的結(jié)果啃匿。與多線程的線程安全不同,可重入強(qiáng)調(diào)對單個(gè)線程執(zhí)行時(shí)重新進(jìn)入同一個(gè)子程序仍然是安全的。
可重入函數(shù)應(yīng)當(dāng)滿足以下條件:
1橙数、不能含有靜態(tài)(全局)非常量數(shù)據(jù)
2灯帮、不能返回靜態(tài)非常量數(shù)據(jù)的地址
3、只能處理由調(diào)用者提供的數(shù)據(jù)钟哥。
4腻贰、不依賴但實(shí)例模式資源的鎖
5播演、調(diào)用(call)函數(shù)也不必然需是可重入的


重入死鎖的概念:重入死鎖在單線程重入的基礎(chǔ)上的擴(kuò)展。當(dāng)一個(gè)線程重新獲取鎖翼闽,讀寫鎖或其他不可重入的同步器時(shí)感局,就可能發(fā)生重入鎖死询微⊥靥幔可重入是線程可以重新獲得它已持有的鎖代态。java的sycharonized塊是可重入的蹦疑。
如何避免重入死鎖:
1萨驶、編寫代碼時(shí)避免再次獲取已經(jīng)持有的鎖腔呜。
2核畴、改寫成可重入鎖

在考慮加鎖時(shí),因盡量避免將執(zhí)行時(shí)間過程的代碼包含在鎖中跟束。

第三章:對象的共享

可見性
加鎖的含義不止是為了互斥行為冀宴,還包括內(nèi)存可見性略贮,為了確保所有線程看到共享變量最新值,所有read and write 操組都必須在同一個(gè)鎖上同步

非原子的64位操組(https://www.zhihu.com/question/38816432
long and double 在64位操作系統(tǒng)中會(huì)將一個(gè)read and write操作分為兩個(gè)32位read and write操作古拴。因此java虛擬機(jī)估計(jì)程序員在long and double上實(shí)現(xiàn)volatile操作黄痪。


Volatile 變量
被標(biāo)記為volatile的java變量”被存儲在主內(nèi)存中”桅打。更準(zhǔn)確的意思指挺尾,每個(gè)變量的讀取都將從當(dāng)前電腦主內(nèi)存中讀取遭铺,并不是從這個(gè)cpu緩存中讀取恢准。每個(gè)變量的寫入操作都將寫入到主內(nèi)存中馁筐,并不只是這個(gè)cpu中。


實(shí)際上果正,jdk5 以后保證 volatile 變量不只是從主內(nèi)存中讀取和寫入.


在多線程中非volatile的變量操作,每個(gè)變量都將從主內(nèi)存中拷貝到 cpu 緩存中攒菠,如果計(jì)算機(jī)有一個(gè)以上的cpu要尔,那么每個(gè)線程可以運(yùn)行在不同的cpu中赵辕,意味著每個(gè)線程變量可以拷貝到不同的cpu緩存中,
在jvm中饲握,使用非volatile變量時(shí)無法保證何時(shí) Reads 數(shù)據(jù)從主內(nèi)存到cpu緩存中或何時(shí)寫入數(shù)據(jù)從cpu緩存到主內(nèi)存中救欧。這會(huì)導(dǎo)致一些問題的發(fā)生笆怠。下面舉例:


有一個(gè)類蹬刷,包含一個(gè)非volatile變量办成。想象一下,如果有一個(gè)線程修改了這個(gè)變量桐汤,但有兩個(gè)線程讀取這個(gè)變量的時(shí)候惊科。因?yàn)檫@個(gè)變量沒被申明為volatile,所以無法保證這個(gè)變量什么時(shí)候從cpu緩存寫入到主內(nèi)存充活。意味著這個(gè)變量的值可以和主內(nèi)存的不一樣。這將導(dǎo)致其他線程無法看到最新值窖张,因?yàn)檫€沒有寫入到主內(nèi)存中。這是一個(gè)“visibility(能見度)”的問題赘淮。


將變量申明為volatile后,所有的寫入操作將立即寫入到主內(nèi)存中走诞。并且所有的讀取操作都將從主內(nèi)存中讀取蚣旱。
volatile 關(guān)鍵字保證不只是讀取和寫入直接訪問主內(nèi)存塞绿,還保證了:
1异吻、如果線程A寫入到volatile變量涧黄,隨后線程b讀取相同的變量笋妥。那么在寫入volatile變量之前線程a可見的非volatile變量,也將在對線程b可見嫉你。開發(fā)人員可以利用這個(gè)延展性月帝,不必為每一個(gè)非volatile變量聲明volatile,只需要為一個(gè)或幾個(gè)變量申明volatile幽污。
public class Exchanger {

private Object   object       = null;
private volatile hasNewObject = false;

public void put(Object newObject) {
    while(hasNewObject) {
        //wait - do not overwrite existing new object
    }
    object = newObject;
    hasNewObject = true; //volatile write
}

public Object take(){
    while(!hasNewObject){ //volatile read
        //wait - don't take old object (or null)
    }
    Object obj = object;
    hasNewObject = false; //volatile write
    return obj;
}

}


2嚷辅、volatile****變量的讀取和寫入不會(huì)被****jvm****重排序(jvm會(huì)重新排序指令保證性能,只要jvm檢測到排序后沒有改變行為).指令前和后可以重排序距误,但是不能混淆volatile的讀取和寫入指令簸搞。無論任何指令讀取或?qū)懭攵急WC發(fā)生在volatile的讀取或?qū)懭胫噶钪螅╓hatever instructions follow a read or write of a volatile variable are guaranteed to happen after the read or write)

while(hasNewObject) {
//wait - do not overwrite existing new object
}
hasNewObject = true; //volatile write
object = newObject;

由于Jvm可以對指令重排序優(yōu)化性能,如果上述代碼被jvm重排序准潭,會(huì)影響object變量的visibility(能見度)趁俊。首先寺擂,線程B可能在看到hasNewObject設(shè)置為true之前,線程A實(shí)際上已經(jīng)為object變量設(shè)置了一個(gè)新的值,現(xiàn)在甚至無法保證為object設(shè)置新值后何時(shí)寫回到主內(nèi)存中。

為了防止發(fā)生上述情況,volatile****附帶“發(fā)生前保證”的特性在****volatile****指令讀取或?qū)懭雸?zhí)行前保證指令不會(huì)發(fā)生改變。volatile 變量執(zhí)行寫入and讀取前后的命令可以重排序矛物,但是volatile指令不能重排序忆首。

volatile****不適用的場景浸锨,當(dāng)一個(gè)volatile被多個(gè)線程執(zhí)行讀取和寫入操作,volatile無法保證原子性,有可能在同一時(shí)刻有多個(gè)線程同時(shí)讀取volatie variable最新的值匈庭,在同時(shí)遞增1 在寫入主內(nèi)存中衷咽,都是直接寫入到主內(nèi)存中躲雅。這種情況導(dǎo)致了競爭條件的發(fā)生,這種情況下應(yīng)該采用synchronized塊來確保讀取和寫入的原子操作。

final和重排序:
在構(gòu)造函數(shù)對一個(gè)final域的寫入和對構(gòu)造對象賦值操作的指令順序不會(huì)被jvm虛擬機(jī)改變。
禁止把final域的寫入操作重排序到構(gòu)造函數(shù)外面植兰,保證了final在對象引用為任意線程可見之前畜挨,完成對final域的初始化,普通域不保證。
初次讀取包含final域的對象與隨后讀取的對象中的final域的指令順序不會(huì)改變。

發(fā)布:當(dāng)一個(gè)對象能夠在當(dāng)前作用域之外的代碼中使用,就稱之為發(fā)布阳距。
逃逸:當(dāng)一個(gè)本不該被發(fā)布的私有對象被其他對象調(diào)用映跟,就稱之為逃逸。例如在對象構(gòu)造完成之前就引用了這個(gè)構(gòu)造對象,就會(huì)破壞線程安全性。
當(dāng)在構(gòu)造函數(shù)沒有返回前,就顯式或者隱式的把構(gòu)造對象發(fā)布出去雷激,會(huì)造成this引用逸出。****不要再構(gòu)造過程中使用this引用逸出

什么是線程封閉:當(dāng)訪問共享的可變的數(shù)據(jù)時(shí)唠帝,通常需要使用同步粪摘。一種避免使用同步的方式就是不共享數(shù)據(jù)玖详。如果僅在單線程內(nèi)訪問數(shù)據(jù)向臀,就不需要同步芹彬。這種技術(shù)被稱為線程封閉(Thread Confinement)

Ad-hoc線程封閉:ad-hoc線程封閉是指,維護(hù)線程封閉性的職責(zé)完全由程序來承擔(dān)瓦宜。并且ad-hoc線程非常脆弱假夺,沒有一種語言特性的支持將對象封裝到目標(biāo)線程中淮蜈。個(gè)人理解就是梧田,所有的狀態(tài)僅在當(dāng)前線程使用穿稳,多個(gè)線程之間的數(shù)據(jù)不共享娩怎,所以難以維護(hù)。

棧封閉:棧封閉是一種線程封閉的特例趁啸。在線程封閉中强缘,只有通過局部變量才能訪問對象。局部變量固有的屬性之一就是封閉在執(zhí)行線程中不傅。其他線程無法訪問這個(gè)棧旅掂。棧封閉也被稱為線程內(nèi)部使用或線程局部使用。比ad-hoc封閉更容易維護(hù)访娶,也更健壯商虐。

ThreadLocal:這個(gè)類能使線程中的某個(gè)值與保存值的對象關(guān)聯(lián)起來。TheadLocal提供了get與set等訪問接口或方法震肮,這些方法為每個(gè)使用該變量的線程存有一份獨(dú)立的副本称龙,因此get總是返回由當(dāng)前線程在調(diào)用set時(shí)設(shè)置的最新值。ThreadLocal通常用于防止對可變的單實(shí)例變量或全局變量進(jìn)行共享戳晌。例如:EJB鲫尊、J2EE容器需要的將一個(gè)事物容器與某個(gè)執(zhí)行中的線程關(guān)聯(lián)起來。通過將事務(wù)上下文保存在靜態(tài)的ThreadLocal對象中沦偎,可以很容易的實(shí)現(xiàn)這個(gè)功能:當(dāng)框架代碼需要判斷當(dāng)前運(yùn)行的是哪個(gè)事物時(shí)疫向,只需要從這個(gè)ThreadLocal對象中讀取事物上下文。缺點(diǎn):使用這個(gè)機(jī)制的代碼與框架耦合在一起豪嚎。threadlocal變量類似于全局變量搔驼,會(huì)降低代碼的可重用性,并在類與類之間引入隱含的耦合性侈询,因此使用時(shí)要格外小心舌涨。


不變性:滿足同步需求的另一個(gè)方法是不可變對象。如果某個(gè)對象在被創(chuàng)建后其狀態(tài)就不能被修改扔字,那么這個(gè)對象就被稱為不可變的對象囊嘉。只要狀態(tài)不改變,那么這些不變形條件就能得以滿足革为。所以不可變對象一定是線程安全的扭粱。在程序設(shè)計(jì)中一個(gè)最困難的地方就是判斷復(fù)雜對象的可能狀態(tài)。不可變對象就不需要判斷惡意代碼或者有問題的代碼破壞震檩,因此可以安全的共享和發(fā)布這些對象琢蛤,而無需創(chuàng)建保護(hù)性副本。最后一個(gè)要求就是“正確的構(gòu)建對象”抛虏,要保證在構(gòu)造過程中防止this逸出博其。

Final域:final域類型的域是不能修改的,但如果final域引用的對象是可變的迂猴,那么這個(gè)被引用的對象是可以修改的贺奠。final域確保了初始化過程的安全性,從而可以不受限制的訪問不可變對象错忱,并在共享這些對象時(shí)無需同步儡率。對象中的可變狀態(tài)越少越好挂据、越簡單。除非需要更高的可見性儿普,否則應(yīng)將所有的域都聲明為私有域崎逃。除非需要某個(gè)域可變,否則應(yīng)將其聲明為final域眉孩。都是良好的編程習(xí)慣个绍。


Final例子:在某些情況下不可變對象能提供一種弱形式的原子性。****Final keywork ****是并發(fā)庫中非常重要但很容易忽略的工具浪汪,需要時(shí)巴柿,final可以確保在構(gòu)建一個(gè)對象時(shí),另一個(gè)線程不能訪問未構(gòu)造完成的對象狀態(tài)死遭。這是因?yàn)楫?dāng)做對象屬性時(shí)广恢,final****有一下重要的特性:在構(gòu)造函數(shù)退出時(shí),****final****字段的值是保證對于其他線程可見的呀潭。


安全發(fā)布的方式:
1钉迷、在靜態(tài)構(gòu)造函數(shù)中初始化一個(gè)對象引用。靜態(tài)初始化器由于jvm的類在初始化階段執(zhí)行钠署。由于在jvm內(nèi)部存在著同步機(jī)制糠聪,因此通過這種方式初始化人和對象都可以安全發(fā)布。
2/谐鼎、將對象引用保存到volatile類型的域或者atomicreferance對象中舰蟆,來確保對象的可見性,和寫入操作的原子性
3狸棍、將對象的引用保存到某個(gè)的正確構(gòu)造對象的final類型域中
4身害、將對象的引用保存到一個(gè)由鎖保護(hù)的域中。


對象安全發(fā)布需求取決于它的可變性:
1隔缀、不可變對象可以通過任意機(jī)制來發(fā)布。
2傍菇、事實(shí)不可變對象必須通過安全方式發(fā)布猾瘸。
3、可變對象必須通過安全方式發(fā)布丢习,并且必須是線程安全的或者由某個(gè)鎖保護(hù)起來


“事實(shí)不可變對象”是什么牵触,在對象發(fā)布后不會(huì)再被修改,那么就足以確保在沒有額外同步的情況下訪問這些對象都是安全的咐低。


可變對象必須保證安全發(fā)布揽思,并且必須是線程安全的或者由某個(gè)鎖保護(hù)起來。


當(dāng)發(fā)布一個(gè)對象是见擦,必須明確的說明對象的訪問方式:
1钉汗、線程封閉:線程封閉的對象只能由一個(gè)線程擁有羹令,對象被封閉在線程中,并且只能由這個(gè)線程修改损痰。

2福侈、只讀共享:在沒有額外的同步情況下,共享的只讀對象可以由多個(gè)線程并發(fā)訪問卢未,但人和線程都不能修改肪凛。共享的只讀對象包括不可變對象和事實(shí)不可變對象,不包含可變對象辽社。

3伟墙、線程安全共享:線程安全的對象在其內(nèi)部實(shí)現(xiàn)同步,因此多個(gè)線程可以通過對象的公有接口來進(jìn)行訪問而不需要進(jìn)一步的同步滴铅。

4戳葵、保護(hù)對象:被保護(hù)的對象只能通過持有特定的鎖來訪問。保護(hù)對象包括封封裝在其他線程安全對象的對象(類似封裝在atomicreferance對象中的對象)失息,以及已發(fā)布的并且由某個(gè)特定鎖保護(hù)的對象譬淳。

第四章:對象的組合

如何設(shè)計(jì)一個(gè)線程安全的類:
1、找出構(gòu)成對象的所有變量

2盹兢、找出約束狀態(tài)變量的不變性條件

3邻梆、建立對象狀態(tài)的并發(fā)訪問管理策略

同步策略(synchroization policy)定義了如何在不違背對象不變條件或后驗(yàn)條件的情況下對其狀態(tài)的訪問操作進(jìn)行協(xié)同。同步策略還規(guī)定了如何將不可變性绎秒、線程封閉與加鎖機(jī)制等結(jié)合以維護(hù)線程的安全性浦妄,并且還規(guī)定了哪兒些變量由哪兒些鎖來保護(hù)。要確保開發(fā)人員可以對類進(jìn)行分析和維護(hù)见芹,就必須將同步策略寫為正式文檔剂娄。

狀態(tài)推斷中,狀態(tài)空間表示狀態(tài)的取值范圍玄呛,狀態(tài)空間越小阅懦,越容易判斷線程的狀態(tài)。final越多越能簡化對象可能狀態(tài)的分析過程徘铝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耳胎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子惕它,更是在濱河造成了極大的恐慌怕午,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件淹魄,死亡現(xiàn)場離奇詭異郁惜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)甲锡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門兆蕉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羽戒,“玉大人,你說我怎么就攤上這事恨樟“胱恚” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵劝术,是天一觀的道長缩多。 經(jīng)常有香客問我,道長养晋,這世上最難降的妖魔是什么衬吆? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮绳泉,結(jié)果婚禮上逊抡,老公的妹妹穿的比我還像新娘。我一直安慰自己零酪,他們只是感情好冒嫡,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著四苇,像睡著了一般孝凌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上月腋,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天蟀架,我揣著相機(jī)與錄音,去河邊找鬼榆骚。 笑死片拍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的妓肢。 我是一名探鬼主播捌省,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼碉钠!你這毒婦竟也來了纲缓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤放钦,失蹤者是張志新(化名)和其女友劉穎色徘,沒想到半個(gè)月后恭金,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體操禀,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年横腿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了颓屑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斤寂。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖揪惦,靈堂內(nèi)的尸體忽然破棺而出遍搞,到底是詐尸還是另有隱情,我是刑警寧澤器腋,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布溪猿,位于F島的核電站,受9級特大地震影響纫塌,放射性物質(zhì)發(fā)生泄漏诊县。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一措左、第九天 我趴在偏房一處隱蔽的房頂上張望依痊。 院中可真熱鬧,春花似錦怎披、人聲如沸胸嘁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽性宏。三九已至,卻和暖如春鱼炒,著一層夾襖步出監(jiān)牢的瞬間衔沼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工昔瞧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留指蚁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓自晰,卻偏偏與公主長得像凝化,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子酬荞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

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