欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java基礎(chǔ)之多線程

 更新時(shí)間:2018年09月14日 14:35:49   作者:小刀愛編程  
以下是我們Java基礎(chǔ)多線程的一些知識(shí)點(diǎn)總結(jié),看完以后會(huì)覺得多線程也可以這么簡單,小編精心推薦,希望能對(duì)大家有所幫助

線程中run()和start()的區(qū)別:
對(duì)于Thread對(duì)象來說,當(dāng)你調(diào)用的是start(),線程會(huì)被放到等待隊(duì)列,等待CPU調(diào)度,不一定馬上執(zhí)行;無需等待run()方法執(zhí)行完畢,可以直接執(zhí)行下面的代碼;
而調(diào)用的是run()的話,就是當(dāng)做普通的方法調(diào)用,程序還是要順序執(zhí)行的;
新建線程的幾種方式:
實(shí)現(xiàn)Runnable接口;里面實(shí)現(xiàn)run()方法;
然后把這個(gè)實(shí)現(xiàn)了Runnable接口的類就新建為一個(gè)Thread t = new Thread(new (實(shí)現(xiàn)Runnable接口的類)),調(diào)用start()方法即可開始一個(gè)線程了。記住,start()只是開啟,然后就會(huì)返回,繼續(xù)執(zhí)行start()下面的語句了。

線程執(zhí)行器:
我們可以通過不同的線程執(zhí)行器來實(shí)現(xiàn)多線程的執(zhí)行,有以下幾種執(zhí)行器:

ExecutorService exec = Executors.newCachedThreadPool();

ExecutorService exec = Executors.newFixedThreadPool(5);

ExecutorService exec = Executors.newSingleThreadExecutor();

我們可以對(duì)比一下這三者的區(qū)別:第一個(gè)執(zhí)行會(huì)為每一個(gè)任務(wù)都創(chuàng)建一個(gè)線程,
而第二個(gè)則是可以一次性指定要分配多少線程,而第三個(gè)則是屬于單線程,會(huì)一個(gè)線程一個(gè)線程的依次執(zhí)行;

休眠:
會(huì)使得任務(wù)中斷一段時(shí)間,相當(dāng)于變相的阻塞了,可以給其他線程制造機(jī)會(huì)去執(zhí)行;
但是我們不能通過sleep()來試圖控制線程的順序執(zhí)行,而是要考慮用同步控制來實(shí)現(xiàn);

讓步:
通過使用yield()方法來給線程調(diào)度機(jī)制一個(gè)暗示:你的工作已經(jīng)完成的差不多了,可以讓別的線程使用CPU了,其功能上跟sleep()其實(shí)是差不多的。

后臺(tái)線程:
指在程序運(yùn)行的時(shí)候在后臺(tái)提供一種通用服務(wù)的線程,并且這種線程并不屬于程序總共不可或缺的部分,當(dāng)所有非后臺(tái)線程結(jié)束時(shí),程序終止;由后臺(tái)線程創(chuàng)建的線程也是后臺(tái)線程;
在線程調(diào)用start()之前,調(diào)用setDaemon(true);

實(shí)現(xiàn)多線程的另一種方式:
通過繼承Thread的方式來實(shí)現(xiàn):而且run()方法是放在構(gòu)造函數(shù)里面的,也就是說,當(dāng)初始化一個(gè)線程的時(shí)候,就自動(dòng)的開啟了線程,記得run()方法里面一般都是一個(gè)while()循環(huán);

加入一個(gè)線程:
一個(gè)線程可以在其他線程之上調(diào)用join()方法,如果某個(gè)線程在另一個(gè)線程t上調(diào)用t.join();此線程將被掛起,知道目標(biāo)線程t結(jié)束才恢復(fù);
join()方法,你在一個(gè)線程中join()了一個(gè)線程進(jìn)來,你就要等待這個(gè)線程結(jié)束了,才可以把自己這個(gè)線程給結(jié)束掉;join()的底層實(shí)現(xiàn)是wait()方法;

同步:
Synchronzied;可以用在方法上,也可以用到類上面;

顯式地使用lock對(duì)象
先用Lock lock = new ReentrantLock();建出一個(gè)鎖對(duì)象出來,然后在方法里面,先調(diào)用lock.lock();然后try語句里面是方法體,最后記得要在finally里面加上lock.unlock();這樣就就相當(dāng)于解鎖了。

區(qū)別:
可以看到synchronized lock相比起來,lock似乎要加上一些try/catch語句才可以,但是,這也是好處之一,比起synchronized,可以多出來處理的過程,讓用戶出現(xiàn)錯(cuò)誤的可能性降低;
使用原子類也可以實(shí)現(xiàn)資源共享的問題,但是原子類一般很少在常規(guī)編程中用到,用于性能調(diào)優(yōu),然后AtomicInteger,AtomicLong等原子類,使用這些的時(shí)候,不需要用到synchronized和lock,但是原子類很少用到,所以我們還是用synchronized和lock。

線程的狀態(tài):
新建;就緒;阻塞;死亡;

導(dǎo)致阻塞的幾個(gè)原因:
1,通過調(diào)用sleep()使任務(wù)進(jìn)入休眠狀態(tài),

2,通過調(diào)用wait()使線程掛起,知道線程得到notify()notifyAll()消息,

3,任務(wù)再等待某個(gè)輸入/輸出完成;

4,任務(wù)視圖在某個(gè)對(duì)象上調(diào)用其同步控制方法,但是對(duì)象鎖不可用,因?yàn)榱硪粋€(gè)任務(wù)已經(jīng)獲取了這個(gè)鎖;

中斷:
這是一個(gè)大學(xué)問呀。一般的話,我們中斷都是用interrupted(),但是,我們現(xiàn)在說了,用Executor執(zhí)行器可以更好地執(zhí)行了,所以我們?nèi)缛绾卧趫?zhí)行器中中斷線程呢?這也很好辦,用Executor的shutdownNow(),但是,這又是一個(gè)問題了,這只是用來中斷所有的線程的,但是我們是想要中斷某一個(gè)線層那該怎么辦呢?這就用到了返回式了,通過submit()來啟動(dòng)任務(wù)的時(shí)候,我們就能夠得到返回的類型Future<?>通過這個(gè)去調(diào)用calcel()來中斷某個(gè)線程。具體等一下碼,現(xiàn)在還要討論的還有一個(gè)問題,中斷的線程是否有一些是無法中斷的,判定如下:如果是在sleep()中的線程,那么顯然是可以中斷的,但是對(duì)于正在讀取I/O的線程和正在試圖獲取鎖的線程,我們是無法中斷的,而中斷線程就相當(dāng)于拋出了一個(gè)異常,方便我們關(guān)閉掉資源。

線程之間的協(xié)作:
當(dāng)線程同時(shí)運(yùn)行多個(gè)任務(wù)時(shí),我們可以用鎖來同步兩個(gè)任務(wù)的行為,同時(shí)也可以用wait()notifyAll()來實(shí)現(xiàn)對(duì)線程的控制;
wait()就是一種掛起的狀態(tài),當(dāng)你掛起了之后,鎖將被釋放,把空出來的線程,給別人執(zhí)行,而等到被調(diào)用notify()喚醒之后,又會(huì)重新獲得之前wait()鎖,如果這個(gè)時(shí)候鎖正在被使用的話,就要陷入等待了。

wait()跟sleep()之間的區(qū)別:
1,在synchronized中,wait()期間對(duì)象鎖是釋放的;而sleep()鎖是不會(huì)釋放的;

2,可以通過notify(),notifyAll(),或者令時(shí)間到期,從wait()中恢復(fù)執(zhí)行;

喚醒的區(qū)別:
notify()方法保證的喚醒是指喚醒的是恰當(dāng)?shù)娜蝿?wù),另外,為了使用notify(),你必須等待相同的條件,而對(duì)于notifyAll()來說,是否所有的線程都會(huì)被喚醒呢?只有當(dāng)notifyAll()因某個(gè)特定鎖被調(diào)用時(shí),只有等待這個(gè)鎖的任務(wù)才能被喚醒;

除了wait()和notify(),我們還可以顯式地使用lock和Condition對(duì)象;
使用互斥并允許任務(wù)掛起的基本類是Condition;可以通過在Condition上調(diào)用await來掛起一個(gè)任務(wù),通過signal()來通知這個(gè)任務(wù),喚醒這個(gè)任務(wù),或者調(diào)用signalAll()來喚醒所有在這個(gè)Condition上被其自身掛起的任務(wù);與使用notify()相比,signlAll()是更安全的方式;

Lock lock = new ReentrantLock();

Condition condition = lock.newCondition();

lock.lock();

lock.unlock();

condition.await();

但是我們要知道顯式的lock對(duì)象,相比起wait(),notify()來說,更加復(fù)雜,所以還是建議用回原來的那個(gè)wait(),LockCondition只有在更加困難的多線程問題才是必需的;

死鎖:
當(dāng)某一個(gè)任務(wù)在等待另一個(gè)任務(wù)的鎖釋放,而下一個(gè)任務(wù)又在等待上一個(gè)鎖的釋放,在這樣呈鏈?zhǔn)降难h(huán)里面,直到這個(gè)鏈條上的任務(wù)又在等待第一個(gè)任務(wù)釋放鎖,得到了一個(gè)任務(wù)之間的相互等待的連續(xù)循環(huán);稱為死鎖;
哲學(xué)家就餐問題;經(jīng)典的死鎖問題;
發(fā)生死鎖的四個(gè)滿足條件:

1,互斥條件,任務(wù)使用的資源中國至少有一個(gè)是不能共享的。

2,至少有一個(gè)任務(wù)它必須持有一個(gè)資源把那個(gè)正在等待獲取另一個(gè)被別的任務(wù)持有的資源;

3,資源不能被任務(wù)搶占;

4,必須要有等待循環(huán);

防止死鎖的最容易的方式是破壞第四個(gè)條件。

總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接

相關(guān)文章

  • Springboot actuator應(yīng)用后臺(tái)監(jiān)控實(shí)現(xiàn)

    Springboot actuator應(yīng)用后臺(tái)監(jiān)控實(shí)現(xiàn)

    這篇文章主要介紹了Springboot actuator應(yīng)用后臺(tái)監(jiān)控實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • SpringBoot實(shí)現(xiàn)多端口監(jiān)聽的代碼示例

    SpringBoot實(shí)現(xiàn)多端口監(jiān)聽的代碼示例

    當(dāng)你需要在同一個(gè)Spring Boot應(yīng)用中,通過不同的端口來提供不同的服務(wù)或功能時(shí),就需要實(shí)現(xiàn)多端口監(jiān)聽,所以本文給大家介紹了SpringBoot實(shí)現(xiàn)多端口監(jiān)聽的方法示例,并有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下
    2024-09-09
  • java后臺(tái)調(diào)用接口及處理跨域問題的解決

    java后臺(tái)調(diào)用接口及處理跨域問題的解決

    這篇文章主要介紹了java后臺(tái)調(diào)用接口,處理跨域的問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Mybatis generator mapper文件覆蓋原文件的示例代碼

    Mybatis generator mapper文件覆蓋原文件的示例代碼

    這篇文章主要介紹了Mybatis generator mapper文件覆蓋原文件,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 解決springboot接入springfox-swagger2遇到的一些問題

    解決springboot接入springfox-swagger2遇到的一些問題

    這篇文章主要介紹了解決springboot接入springfox-swagger2遇到的一些問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 新手初學(xué)Java繼承、封裝與多態(tài)

    新手初學(xué)Java繼承、封裝與多態(tài)

    封裝、繼承、多態(tài)三大特征是java中比較常用的,務(wù)必要掌握,下面給大家介紹Java封裝、繼承、多態(tài)三大特征的理解,有不清楚的朋友可以一起學(xué)習(xí)下
    2021-07-07
  • java編程數(shù)據(jù)類型全面詳解教程新手必入

    java編程數(shù)據(jù)類型全面詳解教程新手必入

    這篇文章主要為大家介紹了java編程數(shù)據(jù)類型全面詳解教程,強(qiáng)烈推薦新手入,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10
  • 在RedisTemplate中使用scan代替keys指令操作

    在RedisTemplate中使用scan代替keys指令操作

    這篇文章主要介紹了在RedisTemplate中使用scan代替keys指令操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • 老生常談Java反射機(jī)制(必看篇)

    老生常談Java反射機(jī)制(必看篇)

    下面小編就為大家?guī)硪黄仙U凧ava反射機(jī)制(必看篇)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • SpringBoot整合Caffeine實(shí)現(xiàn)本地緩存的實(shí)踐分享

    SpringBoot整合Caffeine實(shí)現(xiàn)本地緩存的實(shí)踐分享

    緩存是提升系統(tǒng)性能的一個(gè)不可或缺的工具,通過緩存可以避免大部分重復(fù)的請求到數(shù)據(jù)庫層,減少IO鏈接次數(shù),提升整體的響應(yīng)速率,本地緩存中比較常見的比如 Caffeine 緩存,這篇文章將結(jié)合具體的 Springboot 項(xiàng)目搭配 Caffeine 實(shí)現(xiàn)本地緩存的各種使用方式
    2024-07-07

最新評(píng)論