Java中,關(guān)于多線程操作故慈,你只要看這一篇就夠了

如果對(duì)什么是線程板熊、什么是進(jìn)程仍存有疑惑,請(qǐng)先Google之察绷,因?yàn)檫@兩個(gè)概念不在本文的范圍之內(nèi)干签。

用多線程只有一個(gè)目的,那就是更好的利用cpu的資源拆撼,因?yàn)樗械亩嗑€程代碼都可以用單線程來實(shí)現(xiàn)容劳。說這個(gè)話其實(shí)只有一半對(duì)喘沿,因?yàn)榉磻?yīng)“多角色”的程序代碼,最起碼每個(gè)角色要給他一個(gè)線程吧竭贩,否則連實(shí)際場(chǎng)景都無法模擬蚜印,當(dāng)然也沒法說能用單線程來實(shí)現(xiàn):比如最常見的“生產(chǎn)者,消費(fèi)者模型”留量。

很多人都對(duì)其中的一些概念不夠明確窄赋,如同步、并發(fā)等等楼熄,讓我們先建立一個(gè)數(shù)據(jù)字典忆绰,以免產(chǎn)生誤會(huì)。

多線程:指的是這個(gè)程序(一個(gè)進(jìn)程)運(yùn)行時(shí)產(chǎn)生了不止一個(gè)線程

并行與并發(fā):

并行:多個(gè)cpu實(shí)例或者多臺(tái)機(jī)器同時(shí)執(zhí)行一段處理邏輯可岂,是真正的同時(shí)错敢。

并發(fā):通過cpu調(diào)度算法,讓用戶看上去同時(shí)執(zhí)行缕粹,實(shí)際上從cpu操作層面不是真正的同時(shí)稚茅。并發(fā)往往在場(chǎng)景中有公用的資源,那么針對(duì)這個(gè)公用的資源往往產(chǎn)生瓶頸平斩,我們會(huì)用TPS或者QPS來反應(yīng)這個(gè)系統(tǒng)的處理能力亚享。

請(qǐng)輸入圖片描述

并發(fā)與并行

線程安全:經(jīng)常用來描繪一段代碼。指在并發(fā)的情況之下双戳,該代碼經(jīng)過多線程使用,線程的調(diào)度順序不影響任何結(jié)果糜芳。這個(gè)時(shí)候使用多線程飒货,我們只需要關(guān)注系統(tǒng)的內(nèi)存,cpu是不是夠用即可峭竣。反過來塘辅,線程不安全就意味著線程的調(diào)度順序會(huì)影響最終結(jié)果,如不加事務(wù)的轉(zhuǎn)賬代碼:

void transferMoney(User from, User to, float amount){ ?to.setMoney(to.getBalance() + amount); ?from.setMoney(from.getBalance() - amount); }

同步:Java中的同步指的是通過人為的控制和調(diào)度皆撩,保證共享資源的多線程訪問成為線程安全扣墩,來保證結(jié)果的準(zhǔn)確。如上面的代碼簡單加入

@synchronized

關(guān)鍵字扛吞。在保證結(jié)果準(zhǔn)確的同時(shí)呻惕,提高性能,才是優(yōu)秀的程序滥比。線程安全的優(yōu)先級(jí)高于性能亚脆。

好了,讓我們開始吧盲泛。我準(zhǔn)備分成幾部分來總結(jié)涉及到多線程的內(nèi)容:

扎好馬步:線程的狀態(tài)

內(nèi)功心法:每個(gè)對(duì)象都有的方法(機(jī)制)

太祖長拳:基本線程類

九陰真經(jīng):高級(jí)多線程控制類

扎好馬步:線程的狀態(tài)

先來兩張圖:

請(qǐng)輸入圖片描述

線程狀態(tài)

請(qǐng)輸入圖片描述

線程狀態(tài)轉(zhuǎn)換

各種狀態(tài)一目了然濒持,值得一提的是"blocked"這個(gè)狀態(tài):

線程在Running的過程中可能會(huì)遇到阻塞(Blocked)情況

調(diào)用join()和sleep()方法键耕,sleep()時(shí)間結(jié)束或被打斷,join()中斷,IO完成都會(huì)回到Runnable狀態(tài)柑营,等待JVM的調(diào)度屈雄。

調(diào)用wait(),使該線程處于等待池(wait blocked pool),直到notify()/notifyAll()官套,線程被喚醒被放到鎖定池(lock blocked pool )酒奶,釋放同步鎖使線程回到可運(yùn)行狀態(tài)(Runnable)

對(duì)Running狀態(tài)的線程加同步鎖(Synchronized)使其進(jìn)入(lock blocked pool ),同步鎖被釋放進(jìn)入可運(yùn)行狀態(tài)(Runnable)。

此外虏杰,在runnable狀態(tài)的線程是處于被調(diào)度的線程讥蟆,此時(shí)的調(diào)度順序是不一定的。Thread類中的yield方法可以讓一個(gè)running狀態(tài)的線程轉(zhuǎn)入runnable纺阔。

內(nèi)功心法:每個(gè)對(duì)象都有的方法(機(jī)制)

synchronized, wait, notify 是任何對(duì)象都具有的同步工具瘸彤。讓我們先來了解他們

請(qǐng)輸入圖片描述

monitor

他們是應(yīng)用于同步問題的人工線程調(diào)度工具。講其本質(zhì)笛钝,首先就要明確monitor的概念质况,Java中的每個(gè)對(duì)象都有一個(gè)監(jiān)視器,來監(jiān)測(cè)并發(fā)代碼的重入玻靡。在非多線程編碼時(shí)該監(jiān)視器不發(fā)揮作用结榄,反之如果在synchronized 范圍內(nèi),監(jiān)視器發(fā)揮作用囤捻。

wait/notify必須存在于synchronized塊中臼朗。并且,這三個(gè)關(guān)鍵字針對(duì)的是同一個(gè)監(jiān)視器(某對(duì)象的監(jiān)視器)蝎土。這意味著wait之后视哑,其他線程可以進(jìn)入同步塊執(zhí)行。

當(dāng)某代碼并不持有監(jiān)視器的使用權(quán)時(shí)(如圖中5的狀態(tài)誊涯,即脫離同步塊)去wait或notify挡毅,會(huì)拋出java.lang.IllegalMonitorStateException。也包括在synchronized塊中去調(diào)用另一個(gè)對(duì)象的wait/notify暴构,因?yàn)椴煌瑢?duì)象的監(jiān)視器不同跪呈,同樣會(huì)拋出此異常。

再講用法:

synchronized單獨(dú)使用:

代碼塊:如下取逾,在多線程環(huán)境下耗绿,synchronized塊中的方法獲取了lock實(shí)例的monitor,如果實(shí)例相同砾隅,那么只有一個(gè)線程能執(zhí)行該塊內(nèi)容

public class Thread1 implements Runnable { ? Object lock; ? public void run() { ? ? ? ? synchronized(lock){ ? ? ? ? ..do something ? ? ? } ? } }

直接用于方法: 相當(dāng)于上面代碼中用lock來鎖定的效果缭乘,實(shí)際獲取的是Thread1類的monitor。更進(jìn)一步,如果修飾的是static方法堕绩,則鎖定該類所有實(shí)例腊瑟。

public class Thread1 implements Runnable { ? public synchronized void run() { ? ? ? ? ?..do something ? } }

synchronized, wait, notify結(jié)合:典型場(chǎng)景生產(chǎn)者消費(fèi)者問題

/** ? * 生產(chǎn)者生產(chǎn)出來的產(chǎn)品交給店員 ? */ ?public synchronized void produce() ?{ ? ? ?if(this.product >= MAX_PRODUCT) ? ? ?{ ? ? ? ? ?try ? ? ? ? ?{ ? ? ? ? ? ? ?wait(); ? ? ? ? ? ? ? ?System.out.println("產(chǎn)品已滿,請(qǐng)稍候再生產(chǎn)"); ? ? ? ? ?} ? ? ? ? ?catch(InterruptedException e) ? ? ? ? ?{ ? ? ? ? ? ? ?e.printStackTrace(); ? ? ? ? ?} ? ? ? ? ?return; ? ? ?} ? ? ?this.product++; ? ? ?System.out.println("生產(chǎn)者生產(chǎn)第" + this.product + "個(gè)產(chǎn)品."); ? ? ?notifyAll(); ? //通知等待區(qū)的消費(fèi)者可以取出產(chǎn)品了 ?} ?/** ? * 消費(fèi)者從店員取產(chǎn)品 ? */ ?public synchronized void consume() ?{ ? ? ?if(this.product <= MIN_PRODUCT) ? ? ?{ ? ? ? ? ?try ? ? ? ? ?{ ? ? ? ? ? ? ?wait(); ? ? ? ? ? ? ?System.out.println("缺貨,稍候再取"); ? ? ? ? ?} ? ? ? ? ?catch (InterruptedException e) ? ? ? ? ?{ ? ? ? ? ? ? ?e.printStackTrace(); ? ? ? ? ?} ? ? ? ? ?return; ? ? ?} ? ? ?System.out.println("消費(fèi)者取走了第" + this.product + "個(gè)產(chǎn)品."); ? ? ?this.product--; ? ? ?notifyAll(); ? //通知等待去的生產(chǎn)者可以生產(chǎn)產(chǎn)品了 ?}

volatile

請(qǐng)輸入圖片描述

volatile

針對(duì)多線程使用的變量如果不是volatile或者final修飾的讯私,很有可能產(chǎn)生不可預(yù)知的結(jié)果(另一個(gè)線程修改了這個(gè)值,但是之后在某線程看到的是修改之前的值)。其實(shí)道理上講同一實(shí)例的同一屬性本身只有一個(gè)副本蓖宦。但是多線程是會(huì)緩存值的尊勿,本質(zhì)上抹腿,volatile就是不去緩存彤路,直接取值。在線程安全的情況下加volatile會(huì)犧牲性能沫浆。

太祖長拳:基本線程類

基本線程類指的是Thread類捷枯,Runnable接口,Callable接口

Thread 類實(shí)現(xiàn)了Runnable接口专执,啟動(dòng)一個(gè)線程的方法:

MyThread my = new MyThread();   my.start();

Thread類相關(guān)方法:

//當(dāng)前線程可轉(zhuǎn)讓cpu控制權(quán)淮捆,讓別的就緒狀態(tài)線程運(yùn)行(切換)

public static Thread.yield() //暫停一段時(shí)間

public static Thread.sleep() ? //在一個(gè)線程中調(diào)用other.join(),將等待other執(zhí)行完后才繼續(xù)本線程。

public join()

//后兩個(gè)函數(shù)皆可以被打斷

public interrupte()

關(guān)于中斷:它并不像stop方法那樣會(huì)中斷一個(gè)正在運(yùn)行的線程本股。線程會(huì)不時(shí)地檢測(cè)中斷標(biāo)識(shí)位攀痊,以判斷線程是否應(yīng)該被中斷(中斷標(biāo)識(shí)值是否為true)。終端只會(huì)影響到wait狀態(tài)拄显、sleep狀態(tài)和join狀態(tài)苟径。被打斷的線程會(huì)拋出InterruptedException。

Thread.interrupted()檢查當(dāng)前線程是否發(fā)生中斷躬审,返回boolean

synchronized在獲鎖的過程中是不能被中斷的棘街。

中斷是一個(gè)狀態(tài)!interrupt()方法只是將這個(gè)狀態(tài)置為true而已承边。所以說正常運(yùn)行的程序不去檢測(cè)狀態(tài)遭殉,就不會(huì)終止,而wait等阻塞方法會(huì)去檢查并拋出異常炒刁。如果在正常運(yùn)行的程序中添加while(!Thread.interrupted()) 恩沽,則同樣可以在中斷后離開代碼體

Thread類最佳實(shí)踐

寫的時(shí)候最好要設(shè)置線程名稱 Thread.name誊稚,并設(shè)置線程組 ThreadGroup翔始,目的是方便管理。在出現(xiàn)問題的時(shí)候里伯,打印線程棧 (jstack -pid) 一眼就可以看出是哪個(gè)線程出的問題城瞎,這個(gè)線程是干什么的。

如何獲取線程中的異常

請(qǐng)輸入圖片描述

不能用try,catch來獲取線程中的異常

Runnable

與Thread類似

Callable

future模式:并發(fā)模式的一種疾瓮,可以有兩種形式脖镀,即無阻塞和阻塞,分別是isDone和get狼电。其中Future對(duì)象用來存放該線程的返回值以及狀態(tài)

ExecutorService e = Executors.newFixedThreadPool(3);

//submit方法有多重參數(shù)版本蜒灰,及支持callable也能夠支持runnable接口類型.

Future future = e.submit(new myCallable()); future.isDone() //return true,false 無阻塞

future.get() // return 返回值弦蹂,阻塞直到該線程運(yùn)行結(jié)束

九陰真經(jīng):高級(jí)多線程控制類

以上都屬于內(nèi)功心法,接下來是實(shí)際項(xiàng)目中常用到的工具了强窖,Java1.5提供了一個(gè)非常高效實(shí)用的多線程包:java.util.concurrent, 提供了大量高級(jí)工具,可以幫助開發(fā)者編寫高效凸椿、易維護(hù)、結(jié)構(gòu)清晰的Java多線程程序翅溺。

1.ThreadLocal類

用處:保存線程的獨(dú)立變量脑漫。對(duì)一個(gè)線程類(繼承自Thread)

當(dāng)使用ThreadLocal維護(hù)變量時(shí),ThreadLocal為每個(gè)使用該變量的線程提供獨(dú)立的變量副本咙崎,所以每一個(gè)線程都可以獨(dú)立地改變自己的副本优幸,而不會(huì)影響其它線程所對(duì)應(yīng)的副本。常用于用戶登錄控制褪猛,如記錄session信息网杆。

實(shí)現(xiàn):每個(gè)Thread都持有一個(gè)TreadLocalMap類型的變量(該類是一個(gè)輕量級(jí)的Map,功能與map一樣握爷,區(qū)別是桶里放的是entry而不是entry的鏈表跛璧。功能還是一個(gè)map。)以本身為key新啼,以目標(biāo)為value追城。

主要方法是get()和set(T a),set之后在map里維護(hù)一個(gè)threadLocal -> a燥撞,get時(shí)將a返回座柱。ThreadLocal是一個(gè)特殊的容器。

2.原子類(AtomicInteger物舒、AtomicBoolean……)

如果使用atomic wrapper class如atomicInteger色洞,或者使用自己保證原子的操作,則等同于synchronized

//返回值為boolean

AtomicInteger.compareAndSet(int expect,int update)

該方法可用于實(shí)現(xiàn)樂觀鎖冠胯,考慮文中最初提到的如下場(chǎng)景:a給b付款10元火诸,a扣了10元,b要加10元荠察。此時(shí)c給b2元置蜀,但是b的加十元代碼約為:

請(qǐng)輸入圖片描述

AtomicReference

對(duì)于AtomicReference 來講,也許對(duì)象會(huì)出現(xiàn)悉盆,屬性丟失的情況盯荤,即oldObject == current,但是oldObject.getPropertyA != current.getPropertyA焕盟。

這時(shí)候秋秤,AtomicStampedReference就派上用場(chǎng)了。這也是一個(gè)很常用的思路,即加上版本號(hào)

3.Lock類

lock: 在java.util.concurrent包內(nèi)灼卢。共有三個(gè)實(shí)現(xiàn):

ReentrantLock

ReentrantReadWriteLock.ReadLock

ReentrantReadWriteLock.WriteLock

主要目的是和synchronized一樣绍哎, 兩者都是為了解決同步問題,處理資源爭端而產(chǎn)生的技術(shù)鞋真。功能類似但有一些區(qū)別蛇摸。

區(qū)別如下:

lock更靈活,可以自由定義多把鎖的枷鎖解鎖順序(synchronized要按照先加的后解順序)

提供多種加鎖方案灿巧,lock 阻塞式, trylock 無阻塞式, lockInterruptily 可打斷式赶袄, 還有trylock的帶超時(shí)時(shí)間版本。

本質(zhì)上和監(jiān)視器鎖(即synchronized是一樣的)

能力越大抠藕,責(zé)任越大饿肺,必須控制好加鎖和解鎖,否則會(huì)導(dǎo)致災(zāi)難盾似。

和Condition類的結(jié)合敬辣。

性能更高,對(duì)比如下圖:

請(qǐng)輸入圖片描述

synchronized和Lock性能對(duì)比

ReentrantLock

可重入的意義在于持有鎖的線程可以繼續(xù)持有零院,并且要釋放對(duì)等的次數(shù)后才真正釋放該鎖溉跃。

使用方法是:

1.先new一個(gè)實(shí)例

static ReentrantLock r=new ReentrantLock();

2.加鎖

r.lock()或r.lockInterruptibly();

此處也是個(gè)不同,后者可被打斷告抄。當(dāng)a線程lock后撰茎,b線程阻塞,此時(shí)如果是lockInterruptibly打洼,那么在調(diào)用b.interrupt()之后龄糊,b線程退出阻塞,并放棄對(duì)資源的爭搶募疮,進(jìn)入catch塊炫惩。(如果使用后者,必須throw interruptable exception 或catch)

3.釋放鎖

r.unlock()

必須做阿浓!何為必須做呢他嚷,要放在finally里面。以防止異常跳出了正常流程芭毙,導(dǎo)致災(zāi)難筋蓖。這里補(bǔ)充一個(gè)小知識(shí)點(diǎn),finally是可以信任的:經(jīng)過測(cè)試稿蹲,哪怕是發(fā)生了OutofMemoryError扭勉,finally塊中的語句執(zhí)行也能夠得到保證鹊奖。

ReentrantReadWriteLock

可重入讀寫鎖(讀寫鎖的一個(gè)實(shí)現(xiàn))

ReentrantReadWriteLock lock = new ReentrantReadWriteLock()   ReadLock r = lock.readLock();   WriteLock w = lock.writeLock();

兩者都有l(wèi)ock,unlock方法苛聘。寫寫,寫讀互斥;讀讀不互斥设哗〕罚可以實(shí)現(xiàn)并發(fā)讀的高效線程安全代碼

4.容器類

這里就討論比較常用的兩個(gè):

BlockingQueue

ConcurrentHashMap

BlockingQueue

阻塞隊(duì)列。該類是java.util.concurrent包下的重要類网梢,通過對(duì)Queue的學(xué)習(xí)可以得知震缭,這個(gè)queue是單向隊(duì)列,可以在隊(duì)列頭添加元素和在隊(duì)尾刪除或取出元素战虏。類似于一個(gè)管  道拣宰,特別適用于先進(jìn)先出策略的一些應(yīng)用場(chǎng)景。普通的queue接口主要實(shí)現(xiàn)有PriorityQueue(優(yōu)先隊(duì)列)烦感,有興趣可以研究

BlockingQueue在隊(duì)列的基礎(chǔ)上添加了多線程協(xié)作的功能:

請(qǐng)輸入圖片描述

BlockingQueue

除了傳統(tǒng)的queue功能(表格左邊的兩列)之外巡社,還提供了阻塞接口put和take,帶超時(shí)功能的阻塞接口offer和poll手趣。put會(huì)在隊(duì)列滿的時(shí)候阻塞晌该,直到有空間時(shí)被喚醒;take在隊(duì) 列空的時(shí)候阻塞绿渣,直到有東西拿的時(shí)候才被喚醒朝群。用于生產(chǎn)者-消費(fèi)者模型尤其好用,堪稱神器中符。

常見的阻塞隊(duì)列有:

ArrayListBlockingQueue

LinkedListBlockingQueue

DelayQueue

SynchronousQueue

ConcurrentHashMap

高效的線程安全哈希map姜胖。請(qǐng)對(duì)比hashTable , concurrentHashMap, HashMap

5.管理類

管理類的概念比較泛,用于管理線程淀散,本身不是多線程的谭期,但提供了一些機(jī)制來利用上述的工具做一些封裝。

了解到的值得一提的管理類:ThreadPoolExecutor和 JMX框架下的系統(tǒng)級(jí)管理類 ThreadMXBean

ThreadPoolExecutor

如果不了解這個(gè)類吧凉,應(yīng)該了解前面提到的ExecutorService隧出,開一個(gè)自己的線程池非常方便:

ExecutorService e = Executors.newCachedThreadPool(); ? ?ExecutorService e = Executors.newSingleThreadExecutor(); ? ?ExecutorService e = Executors.newFixedThreadPool(3);

// 第一種是可變大小線程池,按照任務(wù)數(shù)來分配線程阀捅, ? ?// 第二種是單線程池胀瞪,相當(dāng)于FixedThreadPool(1) ? ?// 第三種是固定大小線程池。 ? ?// 然后運(yùn)行 ? ?e.execute(new MyRunnableImpl());

該類內(nèi)部是通過ThreadPoolExecutor實(shí)現(xiàn)的饲鄙,掌握該類有助于理解線程池的管理凄诞,本質(zhì)上,他們都是ThreadPoolExecutor類的各種實(shí)現(xiàn)版本忍级。請(qǐng)參見javadoc:

ThreadPoolExecutor參數(shù)解釋

corePoolSize:池內(nèi)線程初始值與最小值帆谍,就算是空閑狀態(tài),也會(huì)保持該數(shù)量線程轴咱。

maximumPoolSize:線程最大值汛蝙,線程的增長始終不會(huì)超過該值烈涮。

keepAliveTime:當(dāng)池內(nèi)線程數(shù)高于corePoolSize時(shí),經(jīng)過多少時(shí)間多余的空閑線程才會(huì)被回收窖剑〖崆ⅲ回收前處于wait狀態(tài)

unit:

時(shí)間單位,可以使用TimeUnit的實(shí)例西土,如TimeUnit.MILLISECONDS

workQueue:待入任務(wù)(Runnable)的等待場(chǎng)所讶舰,該參數(shù)主要影響調(diào)度策略,如公平與否需了,是否產(chǎn)生餓死(starving)

threadFactory:線程工廠類跳昼,有默認(rèn)實(shí)現(xiàn),如果有自定義的需要?jiǎng)t需要自己實(shí)現(xiàn)ThreadFactory接口并作為參數(shù)傳入肋乍。

最后庐舟,如果你現(xiàn)在也是在學(xué)習(xí)java,你可以關(guān)注我的微信公眾號(hào):java王者之路住拭。有為Java新手們準(zhǔn)備的零基礎(chǔ)到高級(jí)java學(xué)習(xí)資源挪略,有免費(fèi)公開課、java系統(tǒng)學(xué)習(xí)路徑 等等與大家分享滔岳。歡迎大家關(guān)注杠娱。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市谱煤,隨后出現(xiàn)的幾起案子摊求,更是在濱河造成了極大的恐慌,老刑警劉巖刘离,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件室叉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡硫惕,警方通過查閱死者的電腦和手機(jī)茧痕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恼除,“玉大人踪旷,你說我怎么就攤上這事』砘裕” “怎么了令野?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長徽级。 經(jīng)常有香客問我气破,道長,這世上最難降的妖魔是什么餐抢? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任现使,我火速辦了婚禮低匙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朴下。我一直安慰自己,他們只是感情好苦蒿,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布殴胧。 她就那樣靜靜地躺著,像睡著了一般佩迟。 火紅的嫁衣襯著肌膚如雪团滥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天报强,我揣著相機(jī)與錄音灸姊,去河邊找鬼。 笑死秉溉,一個(gè)胖子當(dāng)著我的面吹牛力惯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播召嘶,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼父晶,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了弄跌?” 一聲冷哼從身側(cè)響起甲喝,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铛只,沒想到半個(gè)月后埠胖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淳玩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年直撤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜕着。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谊惭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侮东,到底是詐尸還是另有隱情圈盔,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布悄雅,位于F島的核電站驱敲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宽闲。R本人自食惡果不足惜众眨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一握牧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧娩梨,春花似錦沿腰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至纽什,卻和暖如春措嵌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芦缰。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工企巢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人让蕾。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓浪规,卻偏偏與公主長得像,于是被迫代替她去往敵國和親探孝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子罗丰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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

  • 引 如果對(duì)什么是線程、什么是進(jìn)程仍存有疑惑再姑,請(qǐng)先Google之萌抵,因?yàn)檫@兩個(gè)概念不在本文的范圍之內(nèi)。 用多線程只有一...
    納達(dá)丶無忌閱讀 100,233評(píng)論 34 885
  • 引 如果對(duì)什么是線程元镀、什么是進(jìn)程仍存有疑惑绍填,請(qǐng)先Google之,因?yàn)檫@兩個(gè)概念不在本文的范圍之內(nèi)栖疑。 用多線程只有一...
    Java架構(gòu)師Carl閱讀 1,397評(píng)論 0 17
  • 本文主要講了java中多線程的使用方法讨永、線程同步、線程數(shù)據(jù)傳遞遇革、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法卿闹、概述等。 首先講...
    李欣陽閱讀 2,442評(píng)論 1 15
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,952評(píng)論 1 18
  • 歡喜說萝快,如果不開心就笑一笑吧锻霎, 憂愁說,在我這里只有悶悶不樂揪漩, “嘿旋恼,憂愁,憂愁奄容,你看流星在起舞冰更!” “唉产徊,歡喜,...
    愛麗絲的月牙兔閱讀 649評(píng)論 0 2