Java多線程基礎(chǔ)知識和Doug Lea 李大爺

基礎(chǔ)知識

1最域、CPU核心數(shù)和線程數(shù)的關(guān)系

  • 多核心:也指單芯片多處理器( Chip Multiprocessors,簡稱CMP),CMP是由美國斯坦福大學(xué)提出的,其思想是將大規(guī)模并行處理器中的SMP(對稱多處理器)集成到同一芯片內(nèi),各個(gè)處理器并行執(zhí)行不同的進(jìn)程相味。這種依靠多個(gè)CPU同時(shí)并行地運(yùn)行程序是實(shí)現(xiàn)超高速計(jì)算的一個(gè)重要方向,稱為并行處理
  • 多線程: Simultaneous Multithreading.簡稱SMT.SMT可通過復(fù)制處理器上的結(jié)構(gòu)狀態(tài),讓同一個(gè)處理器上的多個(gè)線程同步執(zhí)行并共享處理器的執(zhí)行資源可最大限度地實(shí)現(xiàn)寬發(fā)射昭抒、亂序的超標(biāo)量處理,提高處理器運(yùn)算部件的利用率,緩和由于數(shù)據(jù)相關(guān)或 Cache未命中帶來的訪問內(nèi)存延時(shí)歪赢。
    核心數(shù)品抽、線程數(shù):目前主流CPU有雙核遍搞、三核和四核,六核也在2010年發(fā)布疗认。增加核心數(shù)目就是為了增加線程數(shù),因?yàn)椴僮飨到y(tǒng)是通過線程來執(zhí)行任務(wù)的,一般情況下它們是1:1對應(yīng)關(guān)系,也就是說四核CPU一般擁有四個(gè)線程较锡。但 Intel引入超線程技術(shù)后,使核心數(shù)與線程數(shù)形成1:2的關(guān)系业稼,
  • 自己的電腦如下


    image.png

image.png

2、CPU時(shí)間片輪轉(zhuǎn)機(jī)制

  • 時(shí)間片輪轉(zhuǎn)調(diào)度是一種最古老蚂蕴、最簡單盼忌、最公平且使用最廣的算法,又稱RR調(diào)度。每個(gè)進(jìn)程被分配一個(gè)時(shí)間段,稱作它的時(shí)間片,即該進(jìn)程允許運(yùn)行的時(shí)間掂墓。

  • 如果在時(shí)間片結(jié)束時(shí)進(jìn)程還在運(yùn)行,則CPU將被剝奪并分配給另一個(gè)進(jìn)程谦纱。如果進(jìn)程在時(shí)間片結(jié)束前阻塞或結(jié)來,則CPU當(dāng)即進(jìn)行切換。調(diào)度程序所要做的就是維護(hù)一張就緒進(jìn)程列表,當(dāng)進(jìn)程用完它的時(shí)間片后,它被移到隊(duì)列的末尾
    時(shí)間片輪轉(zhuǎn)調(diào)度中唯一有趣的一點(diǎn)是時(shí)間片的長度君编。從一個(gè)進(jìn)程切換到另一個(gè)進(jìn)程是需要定時(shí)間的,包括保存和裝入寄存器值及內(nèi)存映像,更新各種表格和隊(duì)列等跨嘉。假如進(jìn)程切( processwitch),有時(shí)稱為上下文切換( context switch),需要5ms,再假設(shè)時(shí)間片設(shè)為20ms,則在做完20ms有用的工作之后,CPU將花費(fèi)5ms來進(jìn)行進(jìn)程切換。CPU時(shí)間的20%被浪費(fèi)在了管理開銷上了吃嘿。
    為了提高CPU效率,我們可以將時(shí)間片設(shè)為5000ms祠乃。這時(shí)浪費(fèi)的時(shí)間只有0.1%。但考慮到在一個(gè)分時(shí)系統(tǒng)中,如果有10個(gè)交互用戶幾乎同時(shí)按下回車鍵,將發(fā)生什么情況?假設(shè)所有其他進(jìn)程都用足它們的時(shí)間片的話,最后一個(gè)不幸的進(jìn)程不得不等待5s才獲得運(yùn)行機(jī)會兑燥。多數(shù)用戶無法忍受一條簡短命令要5才能做出響應(yīng),同樣的問題在一臺支持多道程序的個(gè)人計(jì)算機(jī)上也會發(fā)
    結(jié)論可以歸結(jié)如下:時(shí)間片設(shè)得太短會導(dǎo)致過多的進(jìn)程切換,降低了CPU效率:而設(shè)得太長又可能引起對短的交互請求的響應(yīng)變差亮瓷。將時(shí)間片設(shè)為100ms通常是一個(gè)比較合理的折衷。

  • 3降瞳、什么是進(jìn)程和線程

  • 進(jìn)程是程序運(yùn)行資源分配的最小單位
    進(jìn)程是操作系統(tǒng)進(jìn)行資源分配的最小單位,其中資源包括:CPU嘱支、內(nèi)存空間蚓胸、磁盤等,同一進(jìn)程中的多條線程共享該進(jìn)程中的全部系統(tǒng)資源,而進(jìn)程和進(jìn)程之間是相互獨(dú)立的。進(jìn)程是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動,進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位除师。
    進(jìn)程是程序在計(jì)算機(jī)上的一次執(zhí)行活動沛膳。當(dāng)你運(yùn)行一個(gè)程序,你就啟動了一個(gè)進(jìn)程。顯然,程序是死的汛聚、靜態(tài)的,進(jìn)程是活的锹安、動態(tài)的。進(jìn)程可以分為系統(tǒng)進(jìn)程和用戶進(jìn)程倚舀。凡是用于完成操作系統(tǒng)的各種功能的進(jìn)程就是系統(tǒng)進(jìn)程,它們就是處于運(yùn)行狀態(tài)下的操作系統(tǒng)本身,用戶進(jìn)程就是所有由你啟動的進(jìn)程叹哭。

  • 線程是cpu調(diào)度的最小單位,必須依賴于進(jìn)程而存在
    線程是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位,它是比進(jìn)程更小的、能獨(dú)立運(yùn)行的基本單位痕貌。線程自己基本上不擁有系統(tǒng)資源,只擁有一點(diǎn)在運(yùn)行中必不可少的資源(如程序計(jì)數(shù)器,一組寄存器和棧),但是它可與同屬一個(gè)進(jìn)程的其他的線程共享進(jìn)程所擁有的全部資源风罩。
    線程無處不在
    任何一個(gè)程序都必須要?jiǎng)?chuàng)建線程,特別是Java不管任何程序都必須啟動一個(gè)main函數(shù)的主線程; Java Web開發(fā)里面的定時(shí)任務(wù)、定時(shí)器芯侥、JSP和 Servlet、異步消息處理機(jī)制,遠(yuǎn)程訪問接口RM等,任何一個(gè)監(jiān)聽事件, onclick的觸發(fā)事件等都離不開線程和并發(fā)的知識乳讥。

  • 4柱查、并行和并發(fā)
    如果有條高速公路A上面并排有8條車道,那么最大的并行車輛就是8輛此條高速公路A同時(shí)并排行走的車輛小于等于8輛的時(shí)候,車輛就可以并行運(yùn)行。

  • CPU也是這個(gè)原理,一個(gè)CPU相當(dāng)于一個(gè)高速公路A,核心數(shù)或者線程數(shù)就相當(dāng)于并排可以通行的車道;而多個(gè)CPU就相當(dāng)于并排有多條高速公路,而每個(gè)高速公路并排有多個(gè)車道云石。

  • 當(dāng)談?wù)摬l(fā)的時(shí)候一定要加個(gè)單位時(shí)間,也就是說單位時(shí)間內(nèi)并發(fā)量是多少?離開了單位時(shí)間其實(shí)是沒有意義的唉工。

  • 綜合來說:
    并發(fā):指應(yīng)用能夠交替執(zhí)行不同的任務(wù),比如單CPU核心下執(zhí)行多線程并非是同時(shí)執(zhí)行多個(gè)任務(wù),如果你開兩個(gè)線程執(zhí)行,就是在你幾乎不可能察覺到的速度不斷去切換這兩個(gè)任務(wù),已達(dá)到"同時(shí)執(zhí)行效果",其實(shí)并不是的,只是計(jì)算機(jī)的速度太快,我們無法察覺到而已.
    并行:指應(yīng)用能夠同時(shí)執(zhí)行不同的任務(wù),例:吃飯的時(shí)候可以邊吃飯邊打電話,這兩件事情可以同時(shí)執(zhí)行

  • 兩者區(qū)別:一個(gè)是交替執(zhí)行,一個(gè)是同時(shí)執(zhí)行.

  • 5、高并發(fā)編程的意義汹忠、好處和注意事項(xiàng)

  • 充分利用CPU的資源

  • 加快響應(yīng)用戶的時(shí)間

  • 可以使你的代碼模塊化,異步化,簡單化
    安卓的ui線程

多線程程序需要注意事項(xiàng)

  • (1)線程之間的安全性
    在同一個(gè)進(jìn)程里面的多線程是資源共享的,也就是都可以訪問同一個(gè)內(nèi)存地址當(dāng)中的一個(gè)變量淋硝。例如:若每個(gè)線程中對全局變量、靜態(tài)變量只有讀操作,而無寫操作,一般來說,這個(gè)全局變量是線程安全的:若有多個(gè)線程同時(shí)執(zhí)行寫操作,一般都需要考慮線程同步,否則就可能影響線程安全

  • (2)線程之間的死循環(huán)過程:這個(gè)特別嚴(yán)重宽菜,死鎖
    為了解決線程之間的安全性引入了Java的鎖機(jī)制,而一不小心就會產(chǎn)生Java線程死鎖的多線程問題,因?yàn)椴煌木€程都在等待那些根本不可能被釋放的鎖,從而導(dǎo)致所有的工作都無法完成

  • (3)線程太多了會將服務(wù)器資源耗盡形成死機(jī)當(dāng)機(jī)

Java里的程序天生就是多線程的

image.png

一個(gè)Java程序從main()方法開始執(zhí)行谣膳,然后按照既定的代碼邏輯執(zhí)行,看似沒有其他線程參與铅乡,但實(shí)際上Java程序天生就是多線程程序继谚,因?yàn)閳?zhí)行main()方法的是一個(gè)名稱為main的線程。

  • [6] Monitor Ctrl-Break //監(jiān)控Ctrl-Break中斷信號的
  • [5] Attach Listener //內(nèi)存dump阵幸,線程dump花履,類信息統(tǒng)計(jì),獲取系統(tǒng)屬性等
  • [4] Signal Dispatcher // 分發(fā)處理發(fā)送給JVM信號的線程
  • [3] Finalizer // 調(diào)用對象finalize方法的線程
  • [2] Reference Handler//清除Reference的線程
  • [1] main //main線程挚赊,用戶程序入

線程的啟動與中止

啟動

啟動線程的方式有:

  • 1诡壁、X extends Thread;,然后X.run
  • 2荠割、X implements Runnable妹卿;然后交給Thread運(yùn)行
  • 3、X implements Callable;然后交給Thread運(yùn)行

第1纽帖、2方式都有一個(gè)缺陷就是:在執(zhí)行完任務(wù)之后無法獲取執(zhí)行結(jié)果宠漩。從Java 1.5開始,就提供了Callable和Future懊直,通過它們可以在任務(wù)執(zhí)行完畢之后得到任務(wù)執(zhí)行結(jié)果扒吁。
但是其實(shí)只有兩種,因?yàn)榈谌N的方式看著像是實(shí)現(xiàn)了Callable的接口室囊,但是呢雕崩,其實(shí)到底還是實(shí)現(xiàn)了Runnable的接口,一個(gè)類實(shí)現(xiàn)了Callable融撞,然后new 出對象盼铁,對象交給FutureTask,然后通過線程start

image.png

1尝偎、看FutureTask這個(gè)類饶火,是實(shí)現(xiàn)了RunnableFuture接口
image.png

2、RunnableFuture繼承了致扯,Runnable的接口和Future接口肤寝,所以到底還是Runnable的之類,所以就只有兩種
image.png


Callable抖僵、Future和FutureTask

Runnable是一個(gè)接口鲤看,在它里面只聲明了一個(gè)run()方法,由于run()方法返回值為void類型耍群,所以在執(zhí)行完任務(wù)之后無法返回任何結(jié)果义桂。


image.png

Callable位于java.util.concurrent包下,它也是一個(gè)接口蹈垢,在它里面也只聲明了一個(gè)方法慷吊,只不過這個(gè)方法叫做call(),這是一個(gè)泛型接口曹抬,call()函數(shù)返回的類型就是傳遞進(jìn)來的V類型罢浇。

Future就是對于具體的Runnable或者Callable任務(wù)的執(zhí)行結(jié)果進(jìn)行取消、查詢是否完成沐祷、獲取結(jié)果嚷闭。必要時(shí)可以通過get方法獲取執(zhí)行結(jié)果,該方法會阻塞直到任務(wù)返回結(jié)果赖临。


image.png

因?yàn)镕uture只是一個(gè)接口胞锰,所以是無法直接用來創(chuàng)建對象使用的,因此就有了下面的FutureTask兢榨。


image.png

FutureTask類實(shí)現(xiàn)了RunnableFuture接口嗅榕,RunnableFuture繼承了Runnable接口和Future接口顺饮,而FutureTask實(shí)現(xiàn)了RunnableFuture接口。所以它既可以作為Runnable被線程執(zhí)行凌那,又可以作為Future得到Callable的返回值兼雄。

事實(shí)上,F(xiàn)utureTask是Future接口的一個(gè)唯一實(shí)現(xiàn)類帽蝶。

要new一個(gè)FutureTask的實(shí)例赦肋,有兩種方法

中止

線程自然終止:要么是run執(zhí)行完成了,要么是拋出了一個(gè)未處理的異常導(dǎo)致線程提前結(jié)束励稳。

手動中止

暫停佃乘、恢復(fù)和停止操作對應(yīng)在線程Thread的API就是suspend()、resume()和stop()驹尼。但是這些API是過期的趣避,也就是不建議使用的。不建議使用的原因主要有:以suspend()方法為例新翎,在調(diào)用后程帕,線程不會釋放已經(jīng)占有的資源(比如鎖),而是占有著資源進(jìn)入睡眠狀態(tài)地啰,這樣容易引發(fā)死鎖問題愁拭。同樣,stop()方法在終結(jié)一個(gè)線程時(shí)不會保證線程的資源正常釋放髓绽,通常是沒有給予線程完成資源釋放工作的機(jī)會敛苇,因此會導(dǎo)致程序可能工作在不確定狀態(tài)下妆绞。正因?yàn)閟uspend()、resume()和stop()方法帶來的副作用,這些方法才被標(biāo)注為不建議使用的過期方法禽笑。

安全的中止則是其他線程通過調(diào)用某個(gè)線程A的interrupt()方法對其進(jìn)行中斷操作, 中斷好比其他線程對該線程打了個(gè)招呼恕洲,“A,你要中斷了”图焰,不代表線程A會立即停止自己的工作启盛,同樣的A線程完全可以不理會這種中斷請求。因?yàn)閖ava里的線程是協(xié)作式的技羔,不是搶占式的僵闯。線程通過檢查自身的中斷標(biāo)志位是否被置為true來進(jìn)行響應(yīng),線程通過方法isInterrupted()來進(jìn)行判斷是否被中斷藤滥,也可以調(diào)用靜態(tài)方法Thread.interrupted()來進(jìn)行判斷當(dāng)前線程是否被中斷鳖粟,不過Thread.interrupted()會同時(shí)將中斷標(biāo)識位改寫為false。

如果一個(gè)線程處于了阻塞狀態(tài)(如線程調(diào)用了thread.sleep拙绊、thread.join向图、thread.wait泳秀、),則在線程在檢查中斷標(biāo)示時(shí)如果發(fā)現(xiàn)中斷標(biāo)示為true榄攀,則會在這些阻塞方法調(diào)用處拋出InterruptedException異常嗜傅,并且在拋出異常后會立即將線程的中斷標(biāo)示位清除,即重新設(shè)置為false檩赢。

不建議自定義一個(gè)取消標(biāo)志位來中止線程的運(yùn)行吕嘀。因?yàn)閞un方法里有阻塞調(diào)用時(shí)會無法很快檢測到取消標(biāo)志,線程必須從阻塞調(diào)用返回后漠畜,才會檢查這個(gè)取消標(biāo)志币他。這種情況下,使用中斷會更好憔狞,因?yàn)楹ぃ弧⒁话愕淖枞椒遥鐂leep等本身就支持中斷的檢查拍冠,二、檢查中斷位的狀態(tài)和檢查取消標(biāo)志位沒什么區(qū)別簇抵,用中斷位的狀態(tài)還可以避免聲明取消標(biāo)志位庆杜,減少資源的消耗。

注意****:處于****死鎖狀態(tài)****的****線程無法被中斷

幾個(gè)方法

  • start()方法讓一個(gè)線程進(jìn)入就緒隊(duì)列等待分配cpu碟摆,分到cpu后才調(diào)用實(shí)現(xiàn)的run()方法晃财,start()方法不能重復(fù)調(diào)用。
  • run方法是業(yè)務(wù)邏輯實(shí)現(xiàn)的地方典蜕,本質(zhì)上和任意一個(gè)類的任意一個(gè)成員方法并沒有任何區(qū)別断盛,可以重復(fù)執(zhí)行,可以被單獨(dú)調(diào)用愉舔。
  • yield()方法:使當(dāng)前線程讓出CPU占有權(quán)钢猛,但讓出的時(shí)間是不可設(shè)定的。也不會釋放鎖資源轩缤,所有執(zhí)行yield()的線程有可能在進(jìn)入到可執(zhí)行狀態(tài)后馬上又被執(zhí)行命迈。
  • join方法:把指定的線程加入到當(dāng)前線程,可以將兩個(gè)交替執(zhí)行的線程合并為順序執(zhí)行的線程火的。比如在線程B中調(diào)用了線程A的Join()方法壶愤,直到線程A執(zhí)行完畢后,才會繼續(xù)執(zhí)行線程B馏鹤。

一張圖

image.png

一個(gè)線程新建征椒,到start()-就緒了,如果獲取join()執(zhí)行權(quán)就會運(yùn)行假瞬,時(shí)間片到期 yield就會從運(yùn)行狀態(tài)轉(zhuǎn)化到就緒
運(yùn)行的狀態(tài)陕靠,可以通過sleep() 到阻塞狀態(tài)迂尝,同時(shí)run()到結(jié)束,也是就是一個(gè)死亡的狀態(tài)剪芥。Stop不建議去使用垄开,因?yàn)檫@樣子會導(dǎo)致線程有很多的碎片化的空間,線程中的任務(wù)沒有去執(zhí)行完成税肪,也可以通過wait 去到阻塞的情況
線程阻塞可以通過 notify notifyAll去喚醒他溉躲,同時(shí)sleep時(shí)間到也可以到就緒的狀態(tài),如果一個(gè)線程處于了阻塞狀態(tài)(如線程調(diào)用了thread.sleep益兄、thread.join锻梳、thread.wait、)净捅,則在線程在檢查中斷標(biāo)示時(shí)如果發(fā)現(xiàn)中斷標(biāo)示為true疑枯,則會在這些阻塞方法調(diào)用處拋出InterruptedException異常,并且在拋出異常后會立即將線程的中

關(guān)于 yield的方法蛔六,在 ConcurrentHashMap 類中的initTable方法中就調(diào)用了

image.png
image.png

關(guān)于Doug Lea 荆永,李大爺,這句話可以這么說:編程不識DougLea国章,寫盡java也枉然

image.png

道格拉斯·李(Douglas S. Lea)是紐約州立大學(xué)奧斯威戈分校計(jì)算機(jī)科學(xué)教授和現(xiàn)任計(jì)算機(jī)科學(xué)系主任具钥,他專門研究并發(fā)編程并發(fā)數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)。他是Java Community Process執(zhí)行委員會的主席液兽,并擔(dān)任JSR 166主席骂删,該委員會將并發(fā)實(shí)用程序添加到Java編程語言中(請參閱Java concurrency)。2010年10月22日四啰,Doug Lea通知Java社區(qū)流程執(zhí)行委員會宁玫,他不贊成連任。 Lea再次當(dāng)選為2012 OpenJDK理事會的一般會員

  • Doug Lea寫的java.util.concurrent備受推崇拟逮。AQS的思想奠基者


    image.png
  • HashMap也是李大爺?shù)慕艹鲋?/p>

    image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末撬统,一起剝皮案震驚了整個(gè)濱河市适滓,隨后出現(xiàn)的幾起案子敦迄,更是在濱河造成了極大的恐慌,老刑警劉巖凭迹,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件罚屋,死亡現(xiàn)場離奇詭異,居然都是意外死亡嗅绸,警方通過查閱死者的電腦和手機(jī)脾猛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鱼鸠,“玉大人猛拴,你說我怎么就攤上這事羹铅。” “怎么了愉昆?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵职员,是天一觀的道長。 經(jīng)常有香客問我跛溉,道長焊切,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任芳室,我火速辦了婚禮专肪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘堪侯。我一直安慰自己嚎尤,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布伍宦。 她就那樣靜靜地躺著诺苹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪雹拄。 梳的紋絲不亂的頭發(fā)上收奔,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機(jī)與錄音滓玖,去河邊找鬼坪哄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛势篡,可吹牛的內(nèi)容都是我干的翩肌。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼禁悠,長吁一口氣:“原來是場噩夢啊……” “哼念祭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起碍侦,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瓷产,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體濒旦,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年尔邓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晾剖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锉矢。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖齿尽,靈堂內(nèi)的尸體忽然破棺而出沈撞,到底是詐尸還是另有隱情,我是刑警寧澤雕什,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布缠俺,位于F島的核電站,受9級特大地震影響贷岸,放射性物質(zhì)發(fā)生泄漏壹士。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一偿警、第九天 我趴在偏房一處隱蔽的房頂上張望躏救。 院中可真熱鬧,春花似錦螟蒸、人聲如沸盒使。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽少办。三九已至,卻和暖如春诵原,著一層夾襖步出監(jiān)牢的瞬間英妓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工绍赛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔓纠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓吗蚌,卻偏偏與公主長得像腿倚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子蚯妇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355