偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

線程池的幾個(gè)面試重要考點(diǎn)

開發(fā) 前端
如果你能把這些在面試的時(shí)候說(shuō)清楚,那么至少在線程池這個(gè)知識(shí)點(diǎn)上,你是沒(méi)有任何問(wèn)題了,這樣就可以愉快并且開心的走下一個(gè)知識(shí)點(diǎn)了。

阿粉有點(diǎn)驚嘆最近的面試題,因?yàn)閺闹暗幕A(chǔ)的面試題,到之后的一些涉及到分布式和微服務(wù)的面試題,再到現(xiàn)在的線程池的一些面試題,反正不同的面試官,就有不同的針對(duì)方向,可能現(xiàn)在的面試官比較想考驗(yàn)?zāi)愕亩喾矫娴哪芰Π桑罱?,一個(gè)讀者就反饋給了阿粉說(shuō),面試官全程就從線程這塊入手,整的自己有點(diǎn)尷尬,但是好在有驚無(wú)險(xiǎn)的入職了,我們來(lái)看看面試官都問(wèn)了什么內(nèi)容?

進(jìn)程和線程的概念,你能說(shuō)一下自己的理解么?這個(gè)問(wèn)題,有點(diǎn)基礎(chǔ),不過(guò)肯定是之后的開胃小菜。

進(jìn)程和線程的關(guān)系

進(jìn)程就是應(yīng)用程序在內(nèi)存中分配的空間,也就是正在運(yùn)行的程序,各個(gè)進(jìn)程之間互不干擾。同時(shí)進(jìn)程保存著程序每一個(gè)時(shí)刻運(yùn)行的狀態(tài)。

讓一個(gè)線程執(zhí)行一個(gè)子任務(wù),這樣一個(gè)進(jìn)程就包含了多個(gè)線程,每個(gè)線程負(fù)責(zé)一個(gè)單獨(dú)的子任務(wù)。

進(jìn)程是一個(gè)獨(dú)立的運(yùn)行環(huán)境,而線程是在進(jìn)程中執(zhí)行的一個(gè)任務(wù)。他們兩個(gè)本質(zhì)的區(qū)別是是否單獨(dú)占有內(nèi)存地址空間及其它系統(tǒng)資源(比如I/O)

總得來(lái)說(shuō)就是,線程是屬于進(jìn)程中的一個(gè)任務(wù),應(yīng)該算是包含的關(guān)系。

進(jìn)程是操作系統(tǒng)進(jìn)行資源分配的基本單位,而線程是操作系統(tǒng)進(jìn)行調(diào)度的基本單位。

多進(jìn)程的方式也可以實(shí)現(xiàn)并發(fā),為什么我們要使用多線程?這個(gè)問(wèn)題就有意思了,你如果不是很了解的話,這個(gè)問(wèn)題還真不好回答。

多進(jìn)程方式確實(shí)可以實(shí)現(xiàn)并發(fā),但使用多線程,是比多進(jìn)程有好處的。

1.進(jìn)程間的通信比較復(fù)雜,而線程間的通信比較簡(jiǎn)單,通常情況下,我們需要使用共享資源,這些資源在線程間的通信比較容易。

2.進(jìn)程是重量級(jí)的,而線程是輕量級(jí)的,故多線程方式的系統(tǒng)開銷更小。

資源浪費(fèi)屬于一方面的有點(diǎn),通信簡(jiǎn)單也是另外一方面的優(yōu)點(diǎn),就憑借這兩點(diǎn)的內(nèi)容,還能選擇多進(jìn)程?

圖片

線程池的內(nèi)容

你在工作中使用過(guò)線程池么?為什么使用線程池?這個(gè)問(wèn)題有點(diǎn)尷尬,為什么這么說(shuō)?

如果你說(shuō)你沒(méi)用過(guò),那你這在面試官這里就相當(dāng)于只寫 CRUD 的邏輯業(yè)務(wù)了,也不整點(diǎn)其他的內(nèi)容。

如果你說(shuō)你用過(guò),你就得回答接下來(lái)的一系列關(guān)于線程池的問(wèn)題了。這個(gè)阿粉還是推薦,實(shí)話實(shí)話,就算你沒(méi)用過(guò),那么也別瞎扯,不然你這給自己挖的坑,肯定自己得跳下去。

那么我們就從為什么使用線程池來(lái)入手分析唄。

首先我們就要思考一件事,不使用線程池的話,創(chuàng)建線程有什么弊端么?

在java中,如果每個(gè)請(qǐng)求到達(dá)就創(chuàng)建一個(gè)新線程,那對(duì)服務(wù)器的資源消耗是不是有點(diǎn)大,創(chuàng)建線程,銷毀線程,創(chuàng)建線程,銷毀線程,然后再各種線程之間來(lái)回的切換,這一來(lái)一回,是不是感覺(jué)資源浪費(fèi)就體現(xiàn)出來(lái)了。

那么線程池會(huì)避免這個(gè)情況么?

這就出來(lái)了優(yōu)點(diǎn)1了

創(chuàng)建/銷毀線程需要消耗系統(tǒng)資源,線程池可以復(fù)用已創(chuàng)建的線程。

雖然這個(gè)優(yōu)點(diǎn)很明確,但是還不是主要原因,主要原因如下:

控制并發(fā)的數(shù)量。并發(fā)數(shù)量過(guò)多,可能會(huì)導(dǎo)致資源消耗過(guò)多,從而造成服務(wù)器崩潰。(主要原因)

可以對(duì)線程做統(tǒng)一管理

分析一下線程池的原理 Java中的線程池頂層接口是Executor接口,但是使用的肯定不是這個(gè),是 ThreadPoolExecutor

我們看看 ThreadPoolExecutor 構(gòu)造函數(shù)

public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}

竟然參數(shù)這么多,分別都代表什么意思呢?

int corePoolSize:該線程池中核心線程數(shù)最大值。

int maximumPoolSize:該線程池中線程總數(shù)最大值。

long keepAliveTime:非核心線程閑置超時(shí)時(shí)長(zhǎng)。

TimeUnit unit:keepAliveTime的單位。

BlockingQueue workQueue:阻塞隊(duì)列,維護(hù)著等待執(zhí)行的Runnable任務(wù)對(duì)象。

corePoolSize核心線程最大值:這個(gè)值怎么確定?

一般這個(gè)問(wèn)題是相對(duì)來(lái)說(shuō)比較棘手的,如果面試官問(wèn)這個(gè)問(wèn)題,那一般的同學(xué)肯定頭大,我知道啥意思,但是這個(gè)怎么設(shè)置,我怎么定義呢?

其實(shí)有個(gè)計(jì)算公式:

最佳線程數(shù)目 = ((線程等待時(shí)間+線程CPU時(shí)間)/線程CPU時(shí)間 )* CPU數(shù)目

= (線程等待時(shí)間與線程CPU時(shí)間之比 + 1* CPU數(shù)目

線程等待時(shí)間所占比例越高,需要越多線程。線程CPU時(shí)間所占比例越高,需要越少線程

maximumPoolSize :線程池中線程總數(shù)最大值

這個(gè)值實(shí)際上就是 核心線程數(shù) + 非核心線程數(shù)量

keepAliveTime: 這個(gè)值如果設(shè)定了,那么非核心線程如果處于閑置狀態(tài)超過(guò)該值,就會(huì)被銷毀。

BlockingQueue:阻塞隊(duì)列

看樣子感覺(jué)像 MQ 里面的東西,想到隊(duì)列,我們就又能聯(lián)想到生產(chǎn)者和消費(fèi)者,這時(shí)候就出現(xiàn)了個(gè)問(wèn)題,為什么要有阻塞隊(duì)列呢?

是不是就出現(xiàn)了消費(fèi)者模式,生產(chǎn)者一直生產(chǎn)資源,消費(fèi)者一直消費(fèi)資源,資源存儲(chǔ)在一個(gè)緩沖池中。

我們?cè)趯?shí)現(xiàn)這個(gè)模式的時(shí)候,多個(gè)線程操作共享變量,于是就帶來(lái)了線程安全性的問(wèn)題,造成重復(fù)消費(fèi)和死鎖,這時(shí)候阻塞隊(duì)列就出現(xiàn)了,當(dāng)緩沖池空了,我們需要阻塞消費(fèi)者,喚醒生產(chǎn)者;當(dāng)緩沖池滿了,我們需要阻塞生產(chǎn)者,喚醒消費(fèi)者。

而BlockingQueue提供了線程安全的隊(duì)列訪問(wèn)方式,并發(fā)包下很多高級(jí)同步類的實(shí)現(xiàn)都是基于BlockingQueue實(shí)現(xiàn)的。

也就是說(shuō),你就只負(fù)責(zé)生產(chǎn)和消費(fèi),安全問(wèn)題,JDK 來(lái)給你保證。

說(shuō)到這里,我們不在繼續(xù)往下延伸了,等下次阿粉直接在吧 BlockingQueue 完全的分析一波,應(yīng)為 BlockingQueue 絕對(duì)得需要一個(gè)長(zhǎng)篇的內(nèi)容才能解釋清楚。

分析完里面的參數(shù),這時(shí)候,就得來(lái)看看線程池是怎么處理線程任務(wù)的,不然那怎么和面試官battle。

線程池是如何處理內(nèi)部的線程任務(wù)的

public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
// 1.當(dāng)前線程數(shù)小于corePoolSize,則調(diào)用addWorker創(chuàng)建核心線程執(zhí)行任務(wù)
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
// 2.如果不小于corePoolSize,則將任務(wù)添加到workQueue隊(duì)列。
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
//如果isRunning返回false(狀態(tài)檢查),則remove這個(gè)任務(wù),然后執(zhí)行拒絕策略。
if (! isRunning(recheck) && remove(command))
reject(command);
//線程池處于running狀態(tài),但是沒(méi)有線程,則創(chuàng)建線程
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//如果放入workQueue失敗,則創(chuàng)建非核心線程執(zhí)行任務(wù),
//如果這時(shí)創(chuàng)建非核心線程失敗(當(dāng)前線程總數(shù)不小于maximumPoolSize時(shí)),就會(huì)執(zhí)行拒絕策略。
else if (!addWorker(command, false))
reject(command);
}

在 execute 方法中,ctl.get()是獲取線程池狀態(tài)。

流程如下:

1,首先線程池判斷基本線程池是否已滿,沒(méi)滿,創(chuàng)建一個(gè)工作線程來(lái)執(zhí)行任務(wù)。滿了,則進(jìn)入下個(gè)流程。

2,其次線程池判斷工作隊(duì)列是否已滿?沒(méi)滿,則將新提交的任務(wù)存儲(chǔ)在工作隊(duì)列里。滿了,則進(jìn)入下個(gè)流程。

3,最后線程池判斷整個(gè)線程池是否已滿,沒(méi)滿,則創(chuàng)建一個(gè)新的工作線程來(lái)執(zhí)行任務(wù),滿了,則交給飽和策略來(lái)處理這個(gè)任務(wù)。

圖片

如果你能把這些在面試的時(shí)候說(shuō)清楚,那么至少在線程池這個(gè)知識(shí)點(diǎn)上,你是沒(méi)有任何問(wèn)題了,這樣就可以愉快并且開心的走下一個(gè)知識(shí)點(diǎn)了。

責(zé)任編輯:武曉燕 來(lái)源: Java極客技術(shù)
相關(guān)推薦

2021-02-05 12:34:33

線程池系統(tǒng)

2024-03-11 18:18:58

項(xiàng)目Spring線程池

2019-01-25 08:15:22

Redis命令內(nèi)存

2024-09-12 08:35:06

2024-04-02 09:45:27

線程池Executors開發(fā)

2024-01-12 10:05:32

線程池代碼

2022-03-02 07:36:37

池化技術(shù)Java線程池

2021-11-29 10:55:11

線程池Java面試

2012-05-15 02:18:31

Java線程池

2024-10-31 09:30:05

線程池工具Java

2024-09-09 15:09:30

2022-09-05 17:49:53

Java線程池

2022-03-14 07:32:06

線程池拒絕策略自定義

2022-03-23 08:51:21

線程池Java面試題

2010-06-25 10:36:27

Java連接池

2024-11-11 00:00:01

線程池工具

2022-03-28 08:31:29

線程池定時(shí)任務(wù)

2020-02-18 14:25:51

Java線程池拒絕策略

2025-05-06 09:32:13

2022-06-24 06:43:57

線程池線程復(fù)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)