Java并發(fā)編程實(shí)踐

內(nèi)部鎖

synchronized塊有兩個(gè)部分:鎖對(duì)象的引用以及保護(hù)的代碼塊检碗。
方法的鎖是方法所在的對(duì)象本身瘩缆,靜態(tài)方法的鎖是Class對(duì)象疤估。
每個(gè)java對(duì)象都可以隱式的作為同步的鎖的角色:這些內(nèi)置的鎖被稱為內(nèi)部鎖(intrinsic locks)或者監(jiān)視器鎖(monitor locks)思灌。獲得內(nèi)部鎖的唯一方法就是:進(jìn)入這個(gè)內(nèi)部鎖保護(hù)的方法或者代碼塊。
內(nèi)部鎖在java中扮演了互斥鎖(mutual exclusion locks舌仍,也被稱為mutex)的角色妒貌。

重進(jìn)入(Reentrancy)

內(nèi)部鎖是可以重進(jìn)入的通危,線程請(qǐng)求別的線程的鎖會(huì)拒絕,自己線程的鎖可以獲得灌曙,根據(jù)計(jì)數(shù)器數(shù)量確認(rèn)菊碟,當(dāng)為0時(shí)釋放鎖。

Java監(jiān)視器模式(Java monitor pattern)

對(duì)于遵循Java監(jiān)視器模式的對(duì)象在刺,會(huì)將對(duì)象所有的可變對(duì)象給封閉起來(lái)逆害,并由對(duì)象自己的內(nèi)置鎖進(jìn)行保護(hù)。

/**
 * @author fenghongyu
 */
public class PrivateLock {
    private Object object = new Object();

    private Integer value;

    public void addValue(Integer val) {
        synchronized (object){
            value +=val;
        }
    }
}

監(jiān)視器模式是一種編碼約定蚣驼,對(duì)于任何一種鎖對(duì)象魄幕,只要自始至終都使用該鎖對(duì)象,都可以用來(lái)保護(hù)對(duì)象的狀態(tài)颖杏。
使用私有對(duì)象鎖纯陨,相比使用公有對(duì)象鎖,有如下好處:
私有的鎖對(duì)象留储,可避免客戶獲取到鎖队丝,僅能通過(guò)方法來(lái)訪問(wèn)鎖,以便合理的參與到它的同步策略中欲鹏。
如果要驗(yàn)證某公有鎖對(duì)象是否被正確使用,需要查詢所有使用到的代碼臭墨,但私有鎖赔嚎,僅需要核對(duì)私有鎖對(duì)象所在的類。

ConcurrentModificationException

對(duì)Collection進(jìn)行迭代的標(biāo)準(zhǔn)方式是使用Iterator胧弛,無(wú)論是顯式的使用還是通過(guò)Java5.0引入的新的for-each循環(huán)語(yǔ)法尤误。當(dāng)存在其他線程并發(fā)修改容器時(shí),使用迭代器(Iterator)不可避免地需要再迭代期間對(duì)容器加鎖结缚。在設(shè)計(jì)同步容器返回的迭代器時(shí)损晤,并沒(méi)有考慮到并發(fā)修改的問(wèn)題,它們是“及時(shí)失敽旖摺(fail-fast)”的尤勋,意思是當(dāng)他們察覺(jué)容器在迭代開(kāi)始后被修改,會(huì)拋出該異常茵宪。
隱藏迭代器
有時(shí)候迭代器是隱藏的最冰,比如是HashSet的toString方法。

死鎖(Deadlock)稀火、饑餓(Starvation)暖哨、活鎖(Livelock)

死鎖,饑餓凰狞,活鎖都屬于多線程情況下的線程活躍性問(wèn)題
死鎖是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過(guò)程中篇裁,由于競(jìng)爭(zhēng)資源或者由于彼此通信而造成的一種阻塞的現(xiàn)象沛慢,若無(wú)外力作用,它們都將無(wú)法推進(jìn)下去达布。
此時(shí)稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖团甲,這些永遠(yuǎn)在互相等待的進(jìn)程稱為死鎖進(jìn)程。
饑餓指的是某一個(gè)或者多個(gè)線程無(wú)法獲得所需要的資源往枣,導(dǎo)致一直無(wú)法執(zhí)行伐庭。
可能的情況包括
線程優(yōu)先級(jí)過(guò)低,高級(jí)的線程不斷搶占它需要的資源
某線程長(zhǎng)時(shí)間占用關(guān)鍵資源不放
與死鎖相比,饑餓是可能在未來(lái)一段時(shí)間內(nèi)解決的(比如高級(jí)線程完成任務(wù),不再瘋狂的執(zhí)行)
活鎖指的是線程都秉承著"謙讓"的原則,主動(dòng)將資源釋放給他人使用,導(dǎo)致資源不斷在多個(gè)線程中跳動(dòng),沒(méi)有一個(gè)線程可以同時(shí)拿到所有的資源而正常執(zhí)行.

ConcurrentHashMap

之前的并發(fā)Hash表使用一個(gè)公共鎖同步每一個(gè)方法分冈,并且嚴(yán)格的限制只能有一個(gè)線程可以同時(shí)訪問(wèn)容器圾另。ConcurrentHashMap使用一個(gè)更加細(xì)化的鎖機(jī)制,叫做分離鎖雕沉。這個(gè)機(jī)制運(yùn)行更深測(cè)的共享訪問(wèn)集乔,任意數(shù)量的讀線程可以并發(fā)訪問(wèn)Map,讀寫(xiě)也可以并發(fā)訪問(wèn)Map坡椒,并且有限數(shù)量的寫(xiě)線程還可以并發(fā)修改Map扰路,為并發(fā)訪問(wèn)帶來(lái)更高的吞吐量,同時(shí)幾乎沒(méi)有損失單個(gè)線程訪問(wèn)的性能倔叼。
ConcurrentHasMap和其他并發(fā)容器一起改進(jìn)了同步容器類汗唱,提供不會(huì)拋出ConcurrentModificationException的迭代器。返回的迭代器具有弱一致性丈攒,而非及時(shí)失敗哩罪。
類似size和isEmpty方法可能并非即時(shí)的。

阻塞隊(duì)列和生產(chǎn)者-消費(fèi)者模式

類庫(kù)中包含一些BlockingQueue的實(shí)現(xiàn)巡验,其中LinkedBlockingQueue和ArrayBlockingQueue是FIFO隊(duì)列际插,PriorityBlockingQueue是一個(gè)按優(yōu)先級(jí)排序的隊(duì)列。最后一個(gè)BlockingQueue的實(shí)現(xiàn)是SynchronousQueue显设。
生產(chǎn)者消費(fèi)者之間要進(jìn)行對(duì)象所有權(quán)安全移交框弛,阻塞隊(duì)列提供了連續(xù)的線程限制來(lái)保證(serial thread confinement)。一個(gè)線程約束的對(duì)象完全由單一線程所有捕捂,但是所有權(quán)可以通過(guò)安全的發(fā)布被“轉(zhuǎn)移”瑟枫,這樣其他的線程中只有唯一一個(gè)能夠得到這個(gè)對(duì)象的訪問(wèn)權(quán),并且保證移交之后原線程不能再訪問(wèn)它指攒。阻塞隊(duì)列可以通過(guò)ConcurrentMap的原子方法remove或者AtomicReference的原子方法compareAndSet來(lái)完成力奋。
雙端隊(duì)列和竊取工作(Deque和BlockQDeque),每一個(gè)消費(fèi)者有自己的雙端隊(duì)列幽七,如果完成之后就去竊取其他消費(fèi)者的雙端隊(duì)列的末端任務(wù)景殷。

阻塞和可中斷的方法

線程會(huì)因?yàn)閹追N原因被阻塞或暫停:等待IO操作結(jié)束,等待獲得一個(gè)鎖,等待從Thread.sleep中喚醒猿挚,或者是等待另一個(gè)線程的計(jì)算結(jié)果咐旧。
當(dāng)一個(gè)線程阻塞時(shí),他通常被掛起绩蜻,并且設(shè)置成線程阻塞的某個(gè)狀態(tài)(BLOCKED铣墨、WAITING、TIMED_WAITING)办绝,等到外部事件的發(fā)生觸發(fā)將線程置回(RUNNABLE)狀態(tài)重新獲得調(diào)度的機(jī)會(huì)伊约。

Synchronizer

Synchronizer是一個(gè)對(duì)象,他根據(jù)本身的狀態(tài)調(diào)節(jié)線程的控制流孕蝉。包含:BlockingQueue(阻塞隊(duì)列)屡律,Semaphore(信號(hào)量)、Barrier(關(guān)卡)降淮、閉鎖(Latch)超埋。
CountDownLatch:比如有一個(gè)任務(wù)A,它要等待其他4個(gè)任務(wù)執(zhí)行完畢之后才能執(zhí)行佳鳖,此時(shí)就可以利用CountDownLatch來(lái)實(shí)現(xiàn)這種功能了霍殴。
CyclicBarrier:假若有若干個(gè)線程都要進(jìn)行寫(xiě)數(shù)據(jù)操作,并且只有所有線程都完成寫(xiě)數(shù)據(jù)操作之后系吩,這些線程才能繼續(xù)做后面的事情来庭,此時(shí)就可以利用CyclicBarrier了
Semaphore:一個(gè)工廠有5臺(tái)機(jī)器,但是有8個(gè)工人穿挨,一臺(tái)機(jī)器同時(shí)只能被一個(gè)工人使用月弛,只有使用完了,其他工人才能繼續(xù)使用絮蒿。那么我們就可以通過(guò)Semaphore來(lái)實(shí)現(xiàn)

FutureTask

FutureTask是一種閉鎖,是通過(guò)Callable實(shí)現(xiàn)的叁鉴,它等價(jià)與一個(gè)可攜帶結(jié)果的Runnable土涝,并且有3個(gè)狀態(tài):等待、運(yùn)行幌墓、完成但壮。完成包括所有方式結(jié)束,正常結(jié)束常侣、取消蜡饵、異常。一旦進(jìn)入完成會(huì)永遠(yuǎn)停在這個(gè)狀態(tài)上胳施。
Future.get的行為依賴于任務(wù)的狀態(tài)溯祸。如果完成可以立刻獲得結(jié)果,否則會(huì)被阻塞到完成為止。

Executor框架

使用有界隊(duì)列防止應(yīng)用程序過(guò)載而耗盡內(nèi)存焦辅。Executor框架提供了一個(gè)靈活的線程池實(shí)現(xiàn)博杖。它為任務(wù)提交任務(wù)執(zhí)行之間的解耦提供了標(biāo)準(zhǔn)的方法,為使用Runnable描述任務(wù)提供了通用的方法筷登。來(lái)ExecutorService擴(kuò)展了Executor的接口剃根,加入了生命周期管理。生命周期有三種前方,運(yùn)行(Running)狈醉,關(guān)閉(Shutting down)和終止(terminated)。一開(kāi)始是運(yùn)行惠险,shutdown的時(shí)候停止接受新任務(wù)同時(shí)等已經(jīng)提交的任務(wù)完成苗傅,terminate(shutdownNow)會(huì)嘗試取消已經(jīng)提交的任務(wù)。關(guān)閉后提交過(guò)來(lái)的任務(wù)會(huì)被拒絕執(zhí)行處理器(rejected execution handler)處理莺匠。
ExecutorService中所有的submit方法都會(huì)返回一個(gè)Future金吗。
大量互相獨(dú)立且同類的任務(wù)進(jìn)行并發(fā)處理,會(huì)將程序的任務(wù)量分配到不同的任務(wù)中趣竣,這樣才能真正獲得性能的提升摇庙。

CompletionService:Executor遇見(jiàn)BlockingQueue

ExecutorCompletionService,在構(gòu)造函數(shù)中創(chuàng)建一個(gè)BlockingQueue遥缕,用其保存Executor執(zhí)行后的結(jié)果卫袒。

中斷與取消

中斷并不會(huì)真正中斷一個(gè)正在運(yùn)行的線程,它僅僅發(fā)出了一個(gè)中斷請(qǐng)求单匣,線程會(huì)在自己方便的時(shí)候中斷(稱之為中斷點(diǎn)夕凝,cancellation point)。
中斷常是現(xiàn)實(shí)取消最明智的選擇

隊(duì)列飽和

當(dāng)一個(gè)有限隊(duì)列飽和后户秤,飽和策略開(kāi)始起作用码秉。ThreadPoolExecutor的飽和策略可以通過(guò)調(diào)用setRejectedExecutionHandler

減小鎖的粒度

通過(guò)分拆鎖(lock splitting) 分離鎖(lock striping)
分離鎖:
ConcurrentHashMap的實(shí)現(xiàn)使用了一組包含16個(gè)鎖的Array,每一個(gè)鎖都守護(hù)HashBucket的1/16鸡号。
分離鎖的缺點(diǎn)是對(duì)容器加鎖獨(dú)占訪問(wèn)更加困難與昂貴了转砖。例如ConcurrentHashMap的值需要擴(kuò)展、重排鲸伴、放入一個(gè)更大的Bucket中時(shí)府蔗,需要獲取所有分離鎖。

在切換時(shí)汞窗,一個(gè)進(jìn)程存儲(chǔ)在處理器各寄存器中的中間數(shù)據(jù)叫做進(jìn)程的上下文姓赤,所以進(jìn)程的切換實(shí)質(zhì)上就是被中止運(yùn)行進(jìn)程與待運(yùn)行進(jìn)程上下文的切換。在進(jìn)程未占用處理器時(shí)仲吏,進(jìn)程 的上下文是存儲(chǔ)在進(jìn)程的私有堆棧中的不铆。

顯示鎖(Explicit Locks)

Lock和ReentrantLock

Java5.0提供了ReentrantLock蝌焚,這并不是內(nèi)部鎖的替代,而是在內(nèi)部鎖受到局限的時(shí)候提供的高級(jí)特性狂男。與內(nèi)部加鎖機(jī)制不同综看,Lock提供了無(wú)條件、可輪詢岖食、定時(shí)的红碑、可中斷的鎖獲取操作,所有加鎖和解鎖的方法都是顯式的泡垃。Lock的實(shí)現(xiàn)必須提供具有與內(nèi)部加鎖相同的內(nèi)存可見(jiàn)性的語(yǔ)義析珊。
內(nèi)部鎖大部分情況下都能很好的工作,但是有一些功能上的局限:不能中斷目前正在等待獲取鎖的線程蔑穴,并且在請(qǐng)求鎖資源失敗必須無(wú)限等待忠寻。
synchronized在離開(kāi)代碼塊自動(dòng)釋放鎖,ReentrantLock必須顯式地在final釋放鎖存和,這是風(fēng)險(xiǎn)點(diǎn)奕剃。

公平性

ReentrantLock提供了兩種公平性的選擇:創(chuàng)建非公平鎖(默認(rèn))或者非公平鎖。
在你需要:可定時(shí)捐腿、可輪詢纵朋、可中斷的鎖獲取操作,公平隊(duì)列或者非塊結(jié)構(gòu)的鎖的時(shí)候再考慮使用ReentrantLock茄袖,否則請(qǐng)考慮使用synchronized操软。

讀寫(xiě)鎖

ReentrantLock實(shí)現(xiàn)了標(biāo)準(zhǔn)的互斥鎖。ReadWriteLock宪祥,讀寫(xiě)鎖維護(hù)了兩個(gè)鎖聂薪,只讀鎖可以被多個(gè)線程獲取,寫(xiě)鎖只能有一個(gè)線程獲取蝗羊,兩個(gè)鎖是互斥的藏澳。
Java語(yǔ)言的同步機(jī)制在底層實(shí)現(xiàn)上只有兩種手段:"互斥"和"協(xié)同".體現(xiàn)在Java語(yǔ)言層面上,就是內(nèi)置鎖和內(nèi)置條件隊(duì)列.內(nèi)置鎖即synchronized。內(nèi)置條件隊(duì)列這個(gè)詞大家或許沒(méi)有聽(tīng)過(guò),他指的是Object.wait(),Object.notify(),Object.notifyAll()三種方法耀找,就是條件隊(duì)列方法(內(nèi)部條件隊(duì)列的API)翔悠。Java每個(gè)對(duì)象都可以作為鎖,每個(gè)對(duì)象也都能作為條件隊(duì)列涯呻。一個(gè)對(duì)象的內(nèi)部鎖和內(nèi)部條件隊(duì)列是相關(guān)的:為了調(diào)用對(duì)象X的任一個(gè)隊(duì)列方法凉驻,必須要持有對(duì)象X的鎖腻要。除非你能檢查狀態(tài)复罐,否則你不能等待條件;除非你能改變狀態(tài)雄家,否則你不能從條件等待隊(duì)列中釋放其他的線程效诅。
首先隊(duì)列大家一定都清楚,一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu).正常的隊(duì)列中存儲(chǔ)的都是對(duì)象,而條件隊(duì)列中存儲(chǔ)的是"處于等待狀態(tài)的線程",這些線程在等待某種特定的條件變成真。正如每個(gè)Java對(duì)象都可以作為一個(gè)鎖,每個(gè)對(duì)象同樣可以作為一個(gè)條件隊(duì)列乱投,這個(gè)對(duì)象的wait,notify,notifgAll就構(gòu)成了內(nèi)部條件隊(duì)列的API咽笼。對(duì)象的內(nèi)置鎖與條件隊(duì)列是相互關(guān)聯(lián)的。要調(diào)用條件隊(duì)列的任何一個(gè)方法戚炫,必須先持有該對(duì)對(duì)象上的鎖剑刑。沒(méi)懂的話多讀幾遍,慢慢理解。
我們都知道,線程是用來(lái)干活的,沒(méi)人想讓線程始終處于等待狀態(tài).因此"條件隊(duì)列中的線程一定是執(zhí)行不下去了才處于等待狀態(tài)",這個(gè)"執(zhí)行不下去的條件"叫做"條件謂詞".
至此双肤,我們知道了3個(gè)重要的概念:鎖施掏,條件謂詞,條件隊(duì)列茅糜。雖然他們的關(guān)系并不復(fù)雜七芭,但是一定要注意,wait()方法的返回并不一定意味著正在等待的條件謂詞變成真了蔑赘。舉個(gè)列子:假設(shè)現(xiàn)在有三個(gè)線程在等待同一個(gè)條件謂詞變成真狸驳,然后另外一個(gè)線程調(diào)用了notifyAll()方法。此時(shí)缩赛,只能有一個(gè)線程離開(kāi)條件隊(duì)列耙箍,另外兩個(gè)線程將仍然需要處于等待狀態(tài),這就是在代碼中使用while(conditioin is not true){this.wait();}而不使用if(condition id not true){this.wait();}的原因峦筒。另外一種情況是:同一個(gè)條件隊(duì)列與多個(gè)條件謂詞互相關(guān)聯(lián)究西。這個(gè)時(shí)候,當(dāng)調(diào)用此條件隊(duì)列的notifyAll()方法時(shí)物喷,某些條件謂詞根本就不會(huì)變成真卤材。

剖析Synchronzer

ReentrantLock和Semaphore這兩個(gè)接口有很多共同點(diǎn)。這些類都扮演了“閥門(mén)”的角色峦失,每次只允許有限數(shù)目的線程通過(guò)它扇丛。它們的實(shí)現(xiàn)都使用到一個(gè)共同的基類,AbstractQueuedSynchronizer(AQS)尉辑,包括CountDownLatch帆精,ReentrancReadWriteLock,SynchronousQueue和FutureTask隧魄。AQS解決了實(shí)現(xiàn)一個(gè)Synchronizer的大量細(xì)節(jié)卓练,比如等待線程的FIFO隊(duì)列。
一個(gè)基于AQS的Synchronizer所執(zhí)行的基本操作购啄,是一些不同形式的獲冉笃蟆(acquire)釋放(release)。為了讓一個(gè)類具有狀態(tài)依賴性狮含,它必須擁有一些狀態(tài)顽悼。同步類中有一些狀態(tài)要管理曼振,AQS管理一個(gè)關(guān)于狀態(tài)信息的單一整數(shù),狀態(tài)信息可以通過(guò)protected類型的getState蔚龙,setState和compareAndSetState等方法進(jìn)行操作冰评。獲取操作可能是獨(dú)占的,像ReentrantLock一樣木羹,也可以是非獨(dú)占的甲雅,像Semaphore和CountDownLatch一樣。
AQS中 維護(hù)了一個(gè)volatile int state(代表共享資源)和一個(gè)FIFO線程等待隊(duì)列(多線程爭(zhēng)用資源被阻塞時(shí)會(huì)進(jìn)入此隊(duì)列)坑填。

原子變量與非阻塞同步機(jī)制

這是java.util.concurrent包中的許多類务荆,例如Semephore和ConcurrentLinkedQueue都提供了比使用synchronized更好的性能和可伸縮性。近來(lái)很多算法的研究都聚焦在非阻塞算法(nonblocking algorithms)上穷遂,這種算法是用低層原子化的機(jī)器指令取代鎖函匕,比如比較并交換(compare-and-swap),保證數(shù)據(jù)在并發(fā)訪問(wèn)下的一致性蚪黑。Java5中的原子變量(atomic variable classes)都能夠高效構(gòu)建非阻塞算法盅惜。原子變量提供了volatile類型變量相同的內(nèi)存語(yǔ)義,同時(shí)還支持額外的原子更新忌穿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末抒寂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子掠剑,更是在濱河造成了極大的恐慌屈芜,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件朴译,死亡現(xiàn)場(chǎng)離奇詭異井佑,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)眠寿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)躬翁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人盯拱,你說(shuō)我怎么就攤上這事盒发。” “怎么了狡逢?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵宁舰,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我奢浑,道長(zhǎng)蛮艰,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任殷费,我火速辦了婚禮印荔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘详羡。我一直安慰自己仍律,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布实柠。 她就那樣靜靜地躺著水泉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪窒盐。 梳的紋絲不亂的頭發(fā)上草则,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音蟹漓,去河邊找鬼炕横。 笑死,一個(gè)胖子當(dāng)著我的面吹牛葡粒,可吹牛的內(nèi)容都是我干的份殿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼嗽交,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼卿嘲!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起夫壁,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤拾枣,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后盒让,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體梅肤,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有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
  • 文/蒙蒙 一缝裤、第九天 我趴在偏房一處隱蔽的房頂上張望屏轰。 院中可真熱鬧,春花似錦憋飞、人聲如沸霎苗。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)唁盏。三九已至,卻和暖如春检眯,著一層夾襖步出監(jiān)牢的瞬間厘擂,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工锰瘸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留刽严,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓避凝,卻偏偏與公主長(zhǎng)得像港庄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子恕曲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344