一文搞懂Java多線程底層邏輯,再也不怕多線程了

      網(wǎng)友投稿 723 2022-05-30

      1、線程是什么

      線程是操作系統(tǒng)調(diào)度的最小單元,也叫輕量級(jí)進(jìn)程。它被包含在進(jìn)程之中,是進(jìn)程中的實(shí)際運(yùn)作單位。同一進(jìn)程可以創(chuàng)建多個(gè)線程,每個(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間。并且能夠訪問共享的內(nèi)存變量。

      總之:線程就是一個(gè)電腦的工作單位,可以直接類比現(xiàn)實(shí)生活中的一個(gè)"勞動(dòng)力"(一個(gè)人)

      舉個(gè)例子,開了一家餐廳,餐廳這個(gè)實(shí)體就是進(jìn)程,餐廳里的服務(wù)員就是線程,餐廳里的座位就是資源(游戲內(nèi)的數(shù)據(jù)),所有的服務(wù)員都可以安排客人就座,多個(gè)服務(wù)員安排座位就是多線程競(jìng)爭(zhēng),鎖也就是去排號(hào)。線程池就是有多個(gè)服務(wù)員一直站在那里等著被呼叫。

      進(jìn)程和線程的區(qū)別可以通俗理解為進(jìn)程是一個(gè)公司,而線程是公司里的工作人員,真正干活的還是個(gè)人

      2、啟動(dòng)線程

      java創(chuàng)建線程的三種方式:

      *繼承Thread類創(chuàng)建線程類*,無(wú)法繼承其他類。

      *實(shí)現(xiàn)Runnable接口*

      *通過Callable和Future創(chuàng)建線程*

      package thread; /** * @author 香菜 */ public class ExtendThread extends Thread { @Override public void run() { System.out.println("ExtendThread");; } } package thread; import java.util.concurrent.Callable; /** * @author 香菜 */ public class ImpCallable implements Callable { @Override public Integer call() throws Exception { System.out.println("Callable "); return 1; } } package thread; import java.util.concurrent.FutureTask; /** * @author 香菜 */ public class Aain { public static void main(String[] args) { new ExtendThread().start(); new Thread(new ImpRunnable()).start(); new Thread(new FutureTask<>(new ImpCallable())).start(); } }

      總結(jié):線程的概念來(lái)自于生活,理解了概念,在項(xiàng)目中思考的時(shí)候只要搞清楚項(xiàng)目的線程模型,基本上不會(huì)遇到太大的問題

      3、線程池

      線程池存在的原因是為了節(jié)省創(chuàng)建線程和銷毀線程的系統(tǒng)損耗,這樣說可能不太好理解,我們直接通俗點(diǎn)解釋。

      我們做了一個(gè)飯館,大家都知道飯館的營(yíng)業(yè)時(shí)間是有周期性的,也就是飯點(diǎn)的時(shí)候客人才多,在其他的時(shí)間飯店里肯定是沒有人的,我們?cè)趺礃庸腿藥兔龋?/p>

      假如我們?cè)诳吹娇腿硕嗟臅r(shí)候感覺招募兩個(gè)店員,然后開始讓他們進(jìn)行干活,飯點(diǎn)過了就開掉,這樣的話就是開啟一個(gè)線程,沒事做了趕緊銷毀掉。這樣的處理邏輯明顯不符合飯館的操作,大家都知道每個(gè)飯館的工作人員基本上都是固定的,為什么這樣吶?首先開啟線程,也就是招聘會(huì)有開銷,比如發(fā)廣告,面試,這些都很費(fèi)時(shí)間,而且招到以后還要培訓(xùn),如果用完之后直接開掉,肯定是不合適的,所以這個(gè)時(shí)候我們需要一些長(zhǎng)期的工作人員維持在店里,也就是線程池了。

      線程池的原理是同樣的:保留一部分的線程在系統(tǒng)內(nèi),避免線程的創(chuàng)建和銷毀的系統(tǒng)消耗,隨取隨用。

      4、線程池的創(chuàng)建

      java中創(chuàng)建線程池的方式一般有兩種:

      通過Executors工廠方法創(chuàng)建

      通過new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue)自定義創(chuàng)建

      通過Executors工廠方法創(chuàng)建

      Executor 提供一種將任務(wù)提交與每個(gè)任務(wù)將如何運(yùn)行的機(jī)制(包括線程使用的細(xì)節(jié)、調(diào)度等)分離開來(lái)的方法。

      相當(dāng)于manager,老板讓manager去執(zhí)行一件任務(wù),具體的是誰(shuí)執(zhí)行,什么時(shí)候執(zhí)行,就不管了。

      介紹幾個(gè)

      內(nèi)置的線程池基本上都在這里

      newScheduledThreadPool 定時(shí)執(zhí)行的線程池

      newCachedThreadPool 緩存使用過的線程

      newFixedThreadPool 固定數(shù)量的線程池

      newWorkStealingPool 將大任務(wù)分解為小任務(wù)的線程池

      通過構(gòu)造函數(shù)創(chuàng)建

      public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) ;

      int corePoolSize :表示線程池的數(shù)量,常態(tài)下的線程數(shù)量

      int maximumPoolSize :表示線程池最大的線程池?cái)?shù)量,極限情況下的最大數(shù)量

      long keepAliveTime :表示線程沒有任務(wù)執(zhí)行時(shí)最多保持多久時(shí)間會(huì)終止。默認(rèn)情況下,只有當(dāng)線程池中的線程數(shù)大于corePoolSize時(shí),keepAliveTime才會(huì)起作用,直到線程池中的線程數(shù)不大于corePoolSize,即當(dāng)線程池中的線程數(shù)大于corePoolSize時(shí),如果一個(gè)線程空閑的時(shí)間達(dá)到keepAliveTime,則會(huì)終止,直到線程池中的線程數(shù)不超過corePoolSize。但是如果調(diào)用了

      TimeUnit unit :參數(shù)keepAliveTime的時(shí)間單位,

      BlockingQueue workQueue : 一個(gè)阻塞隊(duì)列,用來(lái)存儲(chǔ)等待執(zhí)行的任務(wù)

      常見選擇有:

      ArrayBlockingQueue 少用 LinkedBlockingQueue 常用 SynchronousQueue 常用 PriorityBlockingQueue 少用

      ThreadFactory threadFactory :用于設(shè)置創(chuàng)建線程的工廠,可以設(shè)置線程的名字和優(yōu)先級(jí)等等

      RejectedExecutionHandler handler:看類名也能猜到是拒絕處理任務(wù)時(shí)的策略。主要有下面幾種可以選擇

      1、AbortPolicy:直接拋出異常。

      2、CallerRunsPolicy:只用調(diào)用者所在線程來(lái)運(yùn)行任務(wù)。

      3、DiscardOldestPolicy:丟棄隊(duì)列里最近的一個(gè)任務(wù),并執(zhí)行當(dāng)前任務(wù)。

      4、DiscardPolicy:不處理,丟棄掉。

      5、也可以根據(jù)應(yīng)用場(chǎng)景需要來(lái)實(shí)現(xiàn)RejectedExecutionHandler接口自定義策略。如記錄日志或持久化不能處理的任務(wù)。

      5、調(diào)試線程

      多線程的調(diào)試可能是一些同學(xué)不太會(huì),大概說下怎么回事

      下面創(chuàng)建了一個(gè)10個(gè)線程的線程池,并提交了3個(gè)任務(wù),運(yùn)行的時(shí)候生成了三個(gè)線程創(chuàng)建了一個(gè)3個(gè)線程的線程池,提交了3個(gè)任務(wù),運(yùn)行的時(shí)候生成了三個(gè)線程

      一文搞懂Java的多線程底層邏輯,再也不怕多線程了

      ExecutorService executorService = Executors.newFixedThreadPool(3); executorService.submit(()-> System.out.println("1111111111111111111111")); executorService.submit(()-> System.out.println("222222222222222222")); executorService.submit(()-> System.out.println("3333333333333333333333"));

      添加斷點(diǎn):

      添加斷點(diǎn)應(yīng)該每個(gè)同學(xué)都會(huì),就是在調(diào)試的時(shí)候需要注意下面兩個(gè)選項(xiàng)

      All 就是在斷點(diǎn)發(fā)生的時(shí)候,會(huì)將整個(gè)虛擬機(jī)停住,也就是所有的線程都會(huì)暫停

      Thread 就是斷住當(dāng)前線程,其他的線程不收影響,在調(diào)試多線程的時(shí)候一定要選擇這個(gè),測(cè)試多個(gè)線程的并行

      6、synchronized關(guān)鍵字

      每個(gè)java對(duì)象頭中都有鎖狀態(tài)位標(biāo)記。java中在使用synchronize同步的時(shí)候,肯定是涉及到某個(gè)對(duì)象的鎖。因此,在考慮同步的時(shí)候,首先要想到是同步的是哪個(gè)對(duì)象的鎖。

      每個(gè)對(duì)象都和一個(gè)monitor對(duì)象關(guān)聯(lián),主要用來(lái)控制互斥資源的訪問,如果你想要加鎖必須先獲得monitor的批準(zhǔn),如果現(xiàn)在正有線程訪問,會(huì)把申請(qǐng)的線程加入到等待隊(duì)列。在對(duì)臨界資源的加鎖的時(shí)候會(huì)調(diào)用monitor_enter,離開的時(shí)候會(huì)monitorexit 釋放鎖

      1、 無(wú)論synchronized關(guān)鍵字加在方法上還是對(duì)象上,如果它作用的對(duì)象是非靜態(tài)的,則它取得的鎖是對(duì)象;如果synchronized作用的對(duì)象是一個(gè)靜態(tài)方法或一個(gè)類,則它取得的鎖是對(duì)class對(duì)象的鎖,該類所有的對(duì)象同一把鎖。

      2、每個(gè)對(duì)象只有一個(gè)鎖(lock)與之相關(guān)聯(lián),誰(shuí)拿到這個(gè)鎖誰(shuí)就可以運(yùn)行它所控制的那段代碼。

      3、實(shí)現(xiàn)同步是要很大的系統(tǒng)開銷作為代價(jià)的,甚至可能造成死鎖,所以盡量避免無(wú)謂的同步控制,避免做嵌套synchronized 的使用。

      4、synchronized 要盡量控制范圍,不能范圍太大,否則會(huì)損失系統(tǒng)性能。

      Java 任務(wù)調(diào)度 多線程

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:注意力機(jī)制BAM和CBAM詳細(xì)解析(附代碼)
      下一篇:Arthas從入門到實(shí)踐
      相關(guān)文章
      国产亚洲成人在线播放va| 欧洲 亚洲 国产图片综合| 亚洲一区二区三区成人网站 | 亚洲精品少妇30p| 亚洲香蕉网久久综合影视| 亚洲男人的天堂一区二区| 亚洲午夜理论片在线观看| 亚洲字幕AV一区二区三区四区| 亚洲色精品VR一区区三区| 最新亚洲春色Av无码专区| 亚洲伊人久久大香线蕉| 亚洲不卡1卡2卡三卡2021麻豆| 亚洲伊人久久精品| 2017亚洲男人天堂一| 亚洲熟妇无码八V在线播放| 亚洲午夜无码久久久久小说| 亚洲国产成人无码AV在线影院 | 亚洲va久久久噜噜噜久久天堂| 亚洲AV永久无码区成人网站| 亚洲av中文无码乱人伦在线r▽| 亚洲AV成人片色在线观看| 中文字幕亚洲免费无线观看日本| 亚洲国产精品热久久| 99ri精品国产亚洲| 亚洲宅男天堂a在线| 国产亚洲福利在线视频| 国产成人人综合亚洲欧美丁香花| 亚洲6080yy久久无码产自国产| 久久久久久久久无码精品亚洲日韩| 国产亚洲福利一区二区免费看| 亚洲色婷婷综合开心网| 亚洲自偷自偷图片| 亚洲精品免费在线观看| 91亚洲视频在线观看| 亚洲中文字幕一二三四区| 青草久久精品亚洲综合专区| 狠狠色婷婷狠狠狠亚洲综合 | 亚洲国产精品精华液| 亚洲七七久久精品中文国产| 亚洲国产无套无码av电影| 亚洲精品私拍国产福利在线|