更新時(shí)間:2020-04-08 11:04:36 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2736次
用于表示多個(gè)操作“依次處理”。比如把十個(gè)操作交給一個(gè)人來(lái)處理時(shí),這個(gè)人要一個(gè)一個(gè)地按順序來(lái)處理
并行
用于標(biāo)識(shí)多個(gè)操作“同時(shí)處理”。比如十個(gè)操作分給兩個(gè)人處理時(shí),這兩個(gè)人就會(huì)并行來(lái)處理。
并發(fā)
相對(duì)于順序和并行來(lái)說(shuō)比較抽象,用于表示“將一個(gè)操作分割成多個(gè)部分并且允許無(wú)序處理”。比如將十個(gè)操作分成相對(duì)獨(dú)立的兩類,這樣便能夠開(kāi)始并發(fā)處理了。如果一個(gè)人來(lái)處理,這個(gè)人就是順序處理分開(kāi)的并發(fā)操作,而如果是兩個(gè)人,這兩個(gè)人就可以并行處理同一個(gè)操作。
總結(jié)
多線程程序都是并發(fā)處理的。如果CPU只有一個(gè),那么并發(fā)處理就是順序執(zhí)行的,而如果有多個(gè)CPU,那么并發(fā)處理就可能會(huì)并行運(yùn)行。
并發(fā)處理的順序執(zhí)行與并發(fā)處理的并行執(zhí)行示意圖如下所示

線程啟動(dòng)與中止
啟動(dòng)方式
Thread
Runnable
以上兩種方式都需要使用start方法用于啟動(dòng)新的線程,在此需要注意的事情是,啟動(dòng)新線程調(diào)用的是start方法而不是run方法
終止
直到所有的線程都終止后,程序才會(huì)終止。也就是說(shuō),當(dāng)這兩個(gè)線程都終止后,程序才會(huì)終止。
Java程序的終止是指除守護(hù)線程以外的線程全部終止。守護(hù)線程是執(zhí)行后臺(tái)作業(yè)的線程。我們可以通過(guò)setDaemon方法把線程設(shè)置為守護(hù)線程。
小知識(shí)
java.util.concurrent包中包含一個(gè)將線程創(chuàng)建抽象化的ThreadFactory接口。利用該接口,我們可以將Runnable作為傳入?yún)?shù)并通過(guò)new創(chuàng)建Thread實(shí)例的處理隱藏在ThreadFactory內(nèi)部。
Executors類中含有多種創(chuàng)建ThreadFactory的方法,感興趣的可以去看一下源碼
synchronized相關(guān)
synchronized方法
如果聲明一個(gè)方法時(shí),在前面加上關(guān)鍵字synchronized那么這個(gè)方法就只能由一個(gè)線程運(yùn)行。只能由一個(gè)線程運(yùn)行是每次只能由一個(gè)線程運(yùn)行的意思,并不是說(shuō)僅能讓某一特定線程運(yùn)行。這種方法叫做synchronized,有時(shí)也稱為同步方法。
synchronizedvoidmethod(){
...
}
復(fù)制代碼
synchronized代碼塊
如果只是想讓方法中的某一部分由一個(gè)線程運(yùn)行,而非整個(gè)方法,則可使用synchronized代碼塊
synchronized(表達(dá)式){
...
}
復(fù)制代碼
synchronized實(shí)例方法和synchronized代碼塊
假設(shè)有如下synchronized實(shí)例方法
synchronizedvoidmethod(){
...
}
復(fù)制代碼
這跟下面將方法體用synchronized代碼塊包圍起來(lái)是等效的
voidmethod(){
synchronized(this){
...
}
}
復(fù)制代碼
synchronized實(shí)例方法是使用this的鎖來(lái)執(zhí)行線程的互斥處理的
synchronized靜態(tài)方法和synchronized代碼塊
synchronized靜態(tài)方法和synchronized實(shí)例方法是相同的。但是synchronized靜態(tài)方法使用的鎖和synchronized實(shí)例方法使用的鎖是不一樣的
classSomething{
staticsynchronizedvoidmethod(){
...
}
}
復(fù)制代碼
這跟下面將方法體用synchronized代碼塊包圍起來(lái)是等效的
classSomething{
staticvoidmethod(){
synchronized(Something.class){
...
}
}
}
復(fù)制代碼
synchronized靜態(tài)方法是使用該類的類對(duì)象鎖來(lái)執(zhí)行線程的互斥處理的。Something.class是Something類對(duì)應(yīng)的java.lang.class類的實(shí)例
wait、notify和notifyAll
等待隊(duì)列
所有實(shí)例都擁有一個(gè)等待隊(duì)列,它是在實(shí)例的wait方法執(zhí)行后停止操作的線程隊(duì)列。就好比為每個(gè)實(shí)例準(zhǔn)備的線程休息室
在執(zhí)行wait方法后,線程便會(huì)暫停操作,(獲取相關(guān)資料加群:874811168)進(jìn)入等待隊(duì)列這個(gè)休息室。除非發(fā)生下列某一情況,否則線程會(huì)一直在等待隊(duì)列中休眠。
有其他線程的notify方法來(lái)喚醒線程
有其他線程的notifyAll方法來(lái)喚醒線程
有其他線程的interrupt方法來(lái)喚醒線程
wait方法超時(shí)
若要執(zhí)行wait方法,線程必須持有鎖。但如果線程進(jìn)入等待隊(duì)列,便會(huì)釋放其實(shí)例的鎖
notify方法
該方法會(huì)將等待隊(duì)列中的一個(gè)線程去除。同wait方法一樣,若要執(zhí)行notify方法,線程也必須持有要調(diào)用的實(shí)例的鎖。
notify喚醒的線程并不會(huì)在執(zhí)行notify的一瞬間就重新運(yùn)行。因?yàn)樵趫?zhí)行notify的那一瞬間,執(zhí)行notify的線程還持有著鎖,所以其他線程還無(wú)法獲取這個(gè)實(shí)例的鎖
notifyAll方法
notify方法僅喚醒一個(gè)線程,而notifyAll則喚醒所有線程,這是兩者之間唯一的區(qū)別
同wait方法和notify方法一樣,notifyAll方法也只能由持有要調(diào)用的實(shí)例鎖的線程調(diào)用
notify和notifyAll選擇
notify方法和notifyAll方法非常相似,到底該使用哪個(gè)?
實(shí)際上,這很難選擇,由于notify喚醒的線程較少,所以處理速度要比使用notifyAll時(shí)快。但使用notify時(shí),如果處理不好,程序便可能會(huì)停止。一般來(lái)說(shuō),使用notifyAll時(shí)的代碼要比使用notify時(shí)的更為健壯。

以上就是動(dòng)力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“Java基礎(chǔ)學(xué)習(xí):java多線程設(shè)計(jì)模式教程”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)