阿里專家與你分享:你必須了解的Java多線程技術(shù)誊爹!

本次的分享主要圍繞以下兩個方面:

Lambda入門

多線程技術(shù)

一悦即、Lambda入門

Lambda起源于數(shù)學(xué)中的λ演算中的一個匿名函數(shù),從它的起源我們可以知道逼裆,Lambda本身就是一個匿名函數(shù)郁稍,是Java8才推出的亮點(diǎn),體現(xiàn)了函數(shù)式編程的思想〔ǜ剑現(xiàn)在主流的編程語言都包含了函數(shù)式編程的特性艺晴,Java8在進(jìn)化過程中吸收了該特性昼钻,作為面向編程對象的補(bǔ)充。

Lambda基本語法如下圖所示封寞,Lambda語法較為簡單然评,和普通函數(shù)相比,沒有返回值以及函數(shù)名狈究,它的參數(shù)和執(zhí)行語句之間通過->連接碗淌,表示參數(shù)將傳遞到語句中執(zhí)行。Lambda表達(dá)式還有兩種簡化表達(dá)式的方法抖锥,當(dāng)表達(dá)式中只有一個執(zhí)行語句時亿眠,可以省略語句的{};如果接口的抽象方法只有一個形參磅废,()可以省略纳像,只需要參數(shù)的名稱即可。Lambda可以替代特定匿名內(nèi)部類拯勉,Lambda表達(dá)式不能單獨(dú)存在竟趾,在使用時必須繼承函數(shù)式接口。

下圖示例中的第一個Lambda表達(dá)式宫峦,形參列表的數(shù)據(jù)類型會自動推斷岔帽,只需要參數(shù)名稱。

代碼示例:小編推薦一個學(xué)JAVA的學(xué)習(xí)裙【 一三三导绷,九三零犀勒,六九三】,無論你是大牛還是小白妥曲,是想轉(zhuǎn)行還是想入行都可以來了解一起進(jìn)步一起學(xué)習(xí)贾费!裙內(nèi)有開發(fā)工具,很多干貨和技術(shù)資料分享檐盟!

在上圖展示的代碼中铸本,代碼中的匿名內(nèi)部類繼承了Flyable接口,實(shí)現(xiàn)了接口中的fly()方法遵堵。代碼準(zhǔn)備了Lambda表達(dá)式重新實(shí)現(xiàn)了Flyable接口。根據(jù)代碼中的輸出命令怨规,執(zhí)行結(jié)果顯示Lambda表達(dá)式起到了和匿名內(nèi)部類相同的作用陌宿。代碼中,并沒有定義Lambda表達(dá)式的參數(shù)類型波丰,但是我們也可以在Lambda表達(dá)式中定義符合要求的類型flyable=(int t)->System.out.println(“I can fly by Lambda”)壳坪,如果參數(shù)類型與接口中方法參數(shù)類型不一致flyable=(String t)->System.out.println(“I can fly by Lambda”),編譯器就會報(bào)錯掰烟。

假如接口實(shí)現(xiàn)了兩個方法爽蝴,匿名內(nèi)部類可以重寫新的方法沐批。但是,Lambda表達(dá)式?jīng)]法做到這一點(diǎn)蝎亚,編譯后九孩,將會提示發(fā)現(xiàn)有多個需要重寫的抽象方法。因此发框,Lambda表達(dá)式在實(shí)現(xiàn)接口時躺彬,只允許接口中有一個抽象方法,我們將這樣的接口稱為函數(shù)式接口梅惯,Java8中提供了注解@FunctionalInterface檢驗(yàn)接口是否為函數(shù)式接口宪拥,如果不是,注解將會報(bào)錯铣减。另外她君,代碼嘗試使用Lambda表達(dá)式替代抽象類的匿名內(nèi)部類的寫法,但會報(bào)錯葫哗,提示必須繼承函數(shù)式接口缔刹。因此,Lambda可以替代特定匿名內(nèi)部類魄梯,簡化代碼桨螺,但是必須繼承函數(shù)式接口。

二酿秸、多線程技術(shù)

1.進(jìn)程與線程

進(jìn)程是具有一定獨(dú)立功能的程序灭翔,關(guān)于某個數(shù)據(jù)集合上的一次運(yùn)行活動,是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個獨(dú)立單位辣苏。線程是進(jìn)程的一個實(shí)體肝箱,是CPU分配調(diào)度的基本單位,代碼的執(zhí)行體稀蟋。從概念上煌张,我們可以知道進(jìn)程是程序的一次運(yùn)行活動,需要系統(tǒng)進(jìn)行分配和調(diào)度的退客;線程是最終代碼的執(zhí)行體专控,是CPU分配調(diào)度的基本單位。同一個進(jìn)程中可以包括多個線程兜叨,并且線程共享整個進(jìn)程的資源躏率,一個進(jìn)程至少包括一個線程。如果在理解概念時很費(fèi)解茫藏,想要充分理解這些概念误趴,我們可以采用反抽象的方法,即聯(lián)系务傲,我們需要在實(shí)際生活中尋找符合概念描述的事物凉当。舉例說明:我們經(jīng)常說安卓手機(jī)比較卡枣申,手機(jī)上App跑的太多,導(dǎo)致內(nèi)存不足看杭,那么我們在手機(jī)上看到的這些App忠藤,就是一個個程序;在手機(jī)卡頓時泊窘,雙擊home鍵熄驼,看到有App在后臺運(yùn)行,這是我們看到的這些app就是進(jìn)程烘豹。進(jìn)程是需要系統(tǒng)分配資源的瓜贾,資源相當(dāng)于手機(jī)的內(nèi)存。通過這個例子携悯,我們可以加深對進(jìn)程和程序概念上的理解祭芦。另外,我們也可以通過反抽象的方法理解進(jìn)程與線程的概念憔鬼。舉例說明:公司運(yùn)轉(zhuǎn)與員工工作龟劲,這里的公司,我們可以對應(yīng)到程序轴或;進(jìn)程是程序的運(yùn)行活動昌跌,這里的進(jìn)程,我們可以理解為公司的正常運(yùn)轉(zhuǎn)照雁;同時蚕愤,公司想要正常運(yùn)轉(zhuǎn),離不開員工的工作饺蚊,員工是公司運(yùn)轉(zhuǎn)不可分割的實(shí)體萍诱,只有員工才是真正做事的人,因此我們可以將線程類比員工污呼。

小編推薦一個學(xué)JAVA的學(xué)習(xí)裙【 一三三裕坊,九三零,六九三】燕酷,無論你是大牛還是小白籍凝,是想轉(zhuǎn)行還是想入行都可以來了解一起進(jìn)步一起學(xué)習(xí)!裙內(nèi)有開發(fā)工具苗缩,很多干貨和技術(shù)資料分享静浴!

2.線程的生命周期

下圖為線程的狀態(tài)圖。所謂的生命周期挤渐,指的是線程從出生到死亡過程中,經(jīng)歷的一系列狀態(tài)双絮。線程通過創(chuàng)建Thread的一個實(shí)例new Thread()進(jìn)入new新建狀態(tài)浴麻;之后調(diào)用start()方法進(jìn)入等待被分配時間片得问,進(jìn)入runnable狀態(tài);之后软免,線程獲得CPU資源執(zhí)行任務(wù)宫纬,進(jìn)入running狀態(tài);當(dāng)線程執(zhí)行完畢或被其它線程殺死膏萧,線程就進(jìn)入dead死亡狀態(tài)漓骚;如果由于某種原因?qū)е抡谶\(yùn)行的線程讓出CPU并暫停自己的執(zhí)行,即進(jìn)入blocked堵塞狀態(tài)榛泛,在多種條件下蝌蹂,blocked狀態(tài)可以恢復(fù)成runnable狀態(tài),最終在線程重新拿到時間片后曹锨,就可以進(jìn)入running狀態(tài)重新運(yùn)行孤个。在running狀態(tài)下,如果時間片用完了或者線程主動放棄CPU的使用沛简,線程重新回到runnable狀態(tài)齐鲤。

時間片指的是CPU的時間片段,CPU將它的可執(zhí)行時間分成很多片段椒楣,每個片段隨機(jī)分配給處在runnable狀態(tài)下的線程给郊,這樣可以達(dá)到并發(fā)的效果。假設(shè)我有一個單核的CPU捧灰,通過分割很多的時間片淆九,每個程序都有機(jī)會運(yùn)行,仍然可以跑很多的程序凤壁,宏觀上看是并發(fā)的吩屹,但是由于只有一個CPU,實(shí)際上程序還是串行的拧抖。

我們可以通過閱讀JDK的Thread類注釋煤搜,創(chuàng)建并使用線程,如下圖所示唧席。

按照J(rèn)DK的注釋擦盾,下圖代碼中使用了兩種創(chuàng)建線程的方法。由于Runnable是一個函數(shù)式接口淌哟,因此代碼中使用Lambda表達(dá)式替代匿名內(nèi)部類迹卢,再將runnable傳遞給Thread,使用start()啟動線程徒仓。

上述代碼結(jié)果如下圖所示腐碱。在下圖代碼中,如果我們將t.start();替換成t.run(),打印結(jié)果將會變成:

Thread Thread run

Main runnable run.

Main

這說明run()方法并沒有真正啟動線程症见,run()方法只是在當(dāng)前的線程中執(zhí)行了run中的函數(shù)喂走。

3. 線程協(xié)作

小編推薦一個學(xué)JAVA的學(xué)習(xí)裙【 一三三,九三零谋作,六九三】芋肠,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進(jìn)步一起學(xué)習(xí)遵蚜!裙內(nèi)有開發(fā)工具帖池,很多干貨和技術(shù)資料分享!

并行與協(xié)作:線程在并發(fā)的過程中更多的是協(xié)作關(guān)系吭净,就像之前的概念中所提到的睡汹,進(jìn)程是系統(tǒng)資源分配的單位,線程本身并沒有多少分配資源攒钳,除了維護(hù)自己必須的內(nèi)存開銷之外帮孔,線程的所有資源都是在進(jìn)程中。多線程在使用競爭中資源時不撑,存在搶占或者說是共享的關(guān)系文兢。

這時,多線程之間該如何協(xié)作焕檬,是需要我們?nèi)ソ鉀Q的姆坚。我們通過下面的代碼,學(xué)會使用關(guān)鍵字synchronized实愚,以及理解臨界區(qū)兼呵,鎖的概念。

上圖代碼模擬售票操作腊敲。一共有10張票击喂,三個售票員sellerA,seller碰辅,sellerC一起去售票懂昂,sell( )方法模擬售票行為。代碼啟動線程之后没宾,運(yùn)行結(jié)果如下圖所示凌彬。售票員sellerA在一個時間片內(nèi)將sell方法中的代碼全部跑完,票售空循衰,但是sellerB與sellerC在線程并發(fā)時铲敛,也售出了第10張票,存在重復(fù)售票会钝,這樣的操作是不合理的伐蒋。

為了解決重復(fù)售票的問題,我們可以使用Java中提供的同步關(guān)鍵字synchronized修飾sell( )方法,代碼如下圖所示先鱼。使用關(guān)鍵字synchronized修飾后徒蟆,多線程在訪問sell( )方法時,能保證只有一個線程執(zhí)行這個方法型型,當(dāng)前線程執(zhí)行完sell( )方法后,其他線程才能執(zhí)行sell( )方法全蝶。

執(zhí)行上述代碼后闹蒜,輸出結(jié)果如下圖所示。從下面結(jié)果可以看到抑淫,代碼解決了重復(fù)售票的不合理問題绷落,但是仍然只有sellerA一個在售票。原因在于始苇,通過關(guān)鍵字synchronized修飾sell( )方法后砌烁,sellerA在拿到sell( )方法的執(zhí)行權(quán)時,把里面的代碼一口氣執(zhí)行完了催式,也就是將票全部賣出函喉,等sellerA執(zhí)行完后,sellerB和sellerC再執(zhí)行sell( )方法時荣月,票數(shù)已經(jīng)為0管呵,自然會出現(xiàn)下圖中沒有賣出一張票的現(xiàn)象。我們將方法sell( )中的內(nèi)容叫做臨界區(qū)哺窄,當(dāng)一個線程進(jìn)入臨界區(qū)后捐下,其他線程必須等待該線程執(zhí)行完臨界區(qū)內(nèi)容后,才能進(jìn)入該臨界區(qū)萌业。

下圖所示的代碼改善了上述sellerA一口氣賣完所有票的現(xiàn)象坷襟。代碼在方法體內(nèi)使用關(guān)鍵字synchronized,括號中的this表示一個對象或者一個類生年。代碼相較于上面的解決方法婴程,將臨界區(qū)從整個方法縮小到兩行代碼。也就是說多線程在執(zhí)行這兩行代碼時是同步的晶框。

上圖代碼執(zhí)行結(jié)果如下圖所示排抬。從圖中我們可以發(fā)現(xiàn),不再是只有sellerA在賣票授段。并且代碼每次執(zhí)行結(jié)果都是不一樣的蹲蒲,因?yàn)镃PU的時間片是隨機(jī)給出的。上述代碼中的try catch方法塊使線程睡50ms侵贵,延長售票操作的時間届搁,在這段時間內(nèi)可以執(zhí)行其他的操作(比如,將該票給某個顧客)。代碼改善過后卡睦,保證資源不是被獨(dú)占的宴胧,使資源分配均勻。

從上圖我們發(fā)現(xiàn)表锻,存在無效票恕齐,原因在于:假設(shè)當(dāng)前票數(shù)為1,A進(jìn)入臨界區(qū)售票瞬逊,而此時B已經(jīng)進(jìn)行判斷显歧,在臨界區(qū)外等待了。當(dāng)A賣完票后确镊,票數(shù)為0士骤,但是B還是會進(jìn)入臨界區(qū)進(jìn)行售票操作,因此蕾域,出現(xiàn)無效票-1的情況拷肌。這說明代碼需要進(jìn)一步改善。改善后的代碼如下圖所示旨巷。代碼在臨界區(qū)內(nèi)加入判斷條件巨缘,只有票數(shù)大于0時,才會進(jìn)行售票操作契沫,這是常用的雙重檢驗(yàn)方法带猴。經(jīng)過雙重檢驗(yàn)后,運(yùn)行代碼就不會出現(xiàn)無效售票懈万。

下面介紹另外一種單線程同步的方法拴清。代碼如下圖所示。代碼通過Lock接口定義了一個鎖会通,使用ReentrantLock實(shí)現(xiàn)口予。鎖和上面提到的關(guān)鍵字synchronized作用是一樣的,都是定義出一個臨界區(qū)涕侈,讓線程進(jìn)入臨界區(qū)時實(shí)現(xiàn)線程同步沪停。代碼通過lock.lock( )定義臨界區(qū)的初始點(diǎn),使用在try語句塊中定義臨界區(qū)執(zhí)行內(nèi)容, finally語句塊中采用unlock( )方法進(jìn)行解鎖裳涛。在unlock后線程才算真正走出臨界區(qū)木张。使用try,finally的原因在于:如果try中拋出異常端三,如果沒有finally中的解鎖舷礼,線程不會調(diào)用unlock方法,永遠(yuǎn)占用這把鎖郊闯,導(dǎo)致其他線程無法進(jìn)入臨界區(qū)執(zhí)行代碼妻献。在finally中調(diào)用unlock( )方法保證無論什么情況下蛛株,鎖終將被釋放。避免死鎖育拨。

上圖中的代碼谨履,如果線程遇到售賣同一張票,鎖沒有被釋放熬丧,線程將會等待笋粟。改善這種情況的方法是,我們使用10把鎖析蝴,使得每張票都有一把鎖矗钟,當(dāng)線程A售賣某張票時,其他線程可以跳過這張票嫌变,無需等待去賣其他未售出的票」或者腾啥,使用兩把鎖,五張票一把鎖冯吓,這種分段鎖的策略進(jìn)一步提高了并發(fā)的效率倘待。

4. 線程池

線程雖然不占用進(jìn)程中的資源,但在Java中组贺,如果每當(dāng)一個請求到達(dá)就創(chuàng)建一個新線程凸舵,開銷是相當(dāng)大的。并且失尖,如果在一個JVM里創(chuàng)建太多的線程啊奄,可能會導(dǎo)致系統(tǒng)由于過度消耗內(nèi)存導(dǎo)致系統(tǒng)資源不足,為了防止資源不足掀潮,應(yīng)該盡可能減少創(chuàng)建和銷毀線程的次數(shù)菇夸,特別是一些資源耗費(fèi)比較大的線程的創(chuàng)建和銷毀,盡量復(fù)用已有對象來進(jìn)行服務(wù)仪吧,這就線程池技術(shù)產(chǎn)生的原因庄新。如果想要實(shí)現(xiàn)線程的復(fù)用,我們需要繼承線程薯鼠,在run方法中通過循環(huán)不斷從外部獲取runnable的實(shí)現(xiàn)择诈,以此達(dá)到線程復(fù)用的目的。有了復(fù)用后出皇,可以提供線程池羞芍,管理線程,線程池可以控制線程的并發(fā)度恶迈,同時涩金,通過對多個任務(wù)重用線程谱醇,線程創(chuàng)建的開銷就被分?jǐn)偟搅硕鄠€任務(wù)上了,而且由于在請求到達(dá)時線程已經(jīng)存在步做,所以消除了線程創(chuàng)建所帶來的延遲副渴。

下面介紹一下線程池的使用。下圖代碼中展示了ThreadPoolExecutor的構(gòu)造方法全度,下面介紹一下方法中包含的參數(shù)煮剧。

corePoolSize:表示線程池的核心線程數(shù),指線程池中常駐線程的數(shù)量将鸵,核心線程數(shù)會一直在線程池中存活勉盅,除非線程池停止使用被資源回收了。

maximumPoolSize:指線程池所能容納的最大線程數(shù)量顶掉,當(dāng)活動線程數(shù)到達(dá)這個數(shù)值后草娜,后續(xù)的新任務(wù)將會被阻塞。

keepAliveTime:非核心線程閑置時的超時時長痒筒,超過這個時長宰闰,非核心線程就會被回收。當(dāng)ThreadPoolExecutor的allowCoreThreadTimeOut屬性設(shè)置為true時簿透,keepAliveTime同樣會作用于核心線程移袍。

Unit:用于指定keepAliveTime參數(shù)的時間單位。

workQueue:表示線程池中的任務(wù)隊(duì)列(阻塞隊(duì)列)老充,通過線程池的execute方法提交Runnable對象會存儲在這個隊(duì)列中葡盗。

threadFactory:表示線程工廠,為線程池提供創(chuàng)建新線程的功能啡浊。

RejectExecutionHandler:這個參數(shù)表示當(dāng)ThreadPoolExecutor已經(jīng)關(guān)閉或者已經(jīng)飽和時(達(dá)到了最大線程池大小而且工作隊(duì)列已經(jīng)滿)觅够,提供以下幾個策略考慮是否拒絕到達(dá)的任務(wù)。DiscardPolicy:直接忽略提交的任務(wù)

AbortPolicy:忽略提交的任務(wù)巷嚣,在拒絕的同時拋出異常蔚约,通知調(diào)用者拒絕執(zhí)行

CallerRunsPolicy:讓線程池的使用者所在的線程運(yùn)行提交的任務(wù)調(diào)用者

DiscardOlderestPolicy:忽略最早放到隊(duì)列中的任務(wù)

下圖代碼中自定義了一個線程池。通過線程池的submit( )方法提交runnable的實(shí)現(xiàn)涂籽,最終通過線程池的shutdown( )方法關(guān)閉線程池苹祟。

Java包中預(yù)置的線程池有以下幾種:newSingleThreadExecutor;newFixedThreadPool:newCachedThreadPool: newScheduledThreadPool: 但在阿里巴巴的Java開發(fā)中是不建議甚至禁止使用Java預(yù)置線程池的评雌。下圖中的代碼目的是尋找SingleThreadExecutor的bug树枫。

小編推薦一個學(xué)JAVA的學(xué)習(xí)裙【 一三三,九三零景东,六九三】砂轻,無論你是大牛還是小白,是想轉(zhuǎn)行還是想入行都可以來了解一起進(jìn)步一起學(xué)習(xí)斤吐!裙內(nèi)有開發(fā)工具搔涝,很多干貨和技術(shù)資料分享厨喂!上述代碼的運(yùn)行結(jié)果如下圖所示。代碼利用循環(huán)庄呈,無限添加runnable的實(shí)現(xiàn)蜕煌,但是由于單一線程的阻塞隊(duì)列是沒有邊界的,會導(dǎo)致添加的對象過多诬留,耗盡內(nèi)存資源斜纪。因此阿里巴巴開發(fā)手冊是明確禁止使用Java預(yù)置線程池的。

如果對JAVA微服務(wù)文兑、分布式盒刚、高并發(fā)、高可用绿贞、大型互聯(lián)網(wǎng)架構(gòu)技術(shù)因块、面試經(jīng)驗(yàn)交流。小編推薦一個學(xué)JAVA的學(xué)習(xí)裙【 一三三籍铁,九三零贮聂,六九三】,無論你是大牛還是小白寨辩,是想轉(zhuǎn)行還是想入行都可以來了解一起進(jìn)步一起學(xué)習(xí)!裙內(nèi)有開發(fā)工具歼冰,很多干貨和技術(shù)資料分享靡狞!,這些資料都是從各個技術(shù)網(wǎng)站搜集隔嫡、整理出來的甸怕,如果你有好的學(xué)習(xí)資料可以私聊發(fā)我,我會注明出處之后分享給大家腮恩。歡迎分享梢杭,歡迎評論,歡迎轉(zhuǎn)發(fā)秸滴!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末武契,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子荡含,更是在濱河造成了極大的恐慌咒唆,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件释液,死亡現(xiàn)場離奇詭異全释,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)误债,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進(jìn)店門浸船,熙熙樓的掌柜王于貴愁眉苦臉地迎上來妄迁,“玉大人,你說我怎么就攤上這事李命〉翘裕” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵项戴,是天一觀的道長形帮。 經(jīng)常有香客問我,道長周叮,這世上最難降的妖魔是什么辩撑? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮仿耽,結(jié)果婚禮上合冀,老公的妹妹穿的比我還像新娘。我一直安慰自己项贺,他們只是感情好君躺,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著开缎,像睡著了一般棕叫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奕删,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天俺泣,我揣著相機(jī)與錄音,去河邊找鬼完残。 笑死伏钠,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谨设。 我是一名探鬼主播熟掂,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼扎拣!你這毒婦竟也來了赴肚?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤二蓝,失蹤者是張志新(化名)和其女友劉穎尊蚁,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侣夷,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡横朋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了百拓。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琴锭。...
    茶點(diǎn)故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡晰甚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出决帖,到底是詐尸還是另有隱情厕九,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布地回,位于F島的核電站扁远,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏刻像。R本人自食惡果不足惜畅买,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望细睡。 院中可真熱鬧谷羞,春花似錦、人聲如沸溜徙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蠢壹。三九已至嗓违,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間图贸,已是汗流浹背蹂季。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留求妹,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓佳窑,卻偏偏與公主長得像制恍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子神凑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評論 2 359

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

  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對應(yīng)一個進(jìn)程,當(dāng)一個程序進(jìn)入內(nèi)存運(yùn)行時,即變成一個進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    小徐andorid閱讀 2,814評論 3 53
  • ??一個任務(wù)通常就是一個程序净神,每個運(yùn)行中的程序就是一個進(jìn)程。當(dāng)一個程序運(yùn)行時溉委,內(nèi)部可能包含了多個順序執(zhí)行流鹃唯,每個順...
    OmaiMoon閱讀 1,680評論 0 12
  • 好像很久沒有走出去接觸新的人,聽新的故事瓣喊,在得知有這么一個活動時還是買了一張票坡慌,去熏陶熏陶。會上有1位開場嘉賓和7...
    佳麗Lavinia閱讀 2,082評論 0 0
  • 1. hello world 是編程的入門級藻三。 2. 后臺語言是Python相對語法簡單些洪橘。 3. 引入相對應(yīng)的模...
    不見長安丶灬閱讀 518評論 0 0
  • 不知道為何而來跪者, 不知要去往何處。 白白走了一遭熄求, 無能又委屈渣玲, 平靜又絕望。
    大橙子樹閱讀 166評論 0 0