java高頻率面試題_第1頁
java高頻率面試題_第2頁
java高頻率面試題_第3頁
java高頻率面試題_第4頁
java高頻率面試題_第5頁
已閱讀5頁,還剩61頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

力口油YES,ICAN

==和equals的區(qū)別

基本類型比較的是數(shù)值

*引用類型比較的堆內(nèi)存中的地址

關(guān)equk

"字符串比較的是值,因為重寫了StHng的

StringStrngBufferStringBuild

SWing長度不可變,追加或修改數(shù)據(jù)會產(chǎn)生新的對象(消耗系統(tǒng)資源)

為Stri八gBuffer支持追加,多線程安全,效率必StH八gBUildsg八ch/Ohized

包裹

*StringBuild支持追加,線程不安全,效率高

局部內(nèi)部類或者匿名內(nèi)部類,使用局部變量為啥要用final

修飾

1.從編譯分析:會被編譯成倆個.dass文件,主函數(shù)結(jié)束不意味著他們結(jié)束,主

函數(shù)的局部變量會被JVMgc回收,產(chǎn)生調(diào)用不存在的變量

興2.從數(shù)據(jù)一致性方面考慮:內(nèi)部類修改變量,外面函數(shù)無法感知數(shù)據(jù)變化,會

產(chǎn)生數(shù)據(jù)不一致問題

final關(guān)鍵字的功能概述

1.如果引用為基本數(shù)據(jù)類型,則該引用為常量,該值無法修改;

2.如果引用為引用數(shù)據(jù)類型,比如對象、數(shù)組,則該對象、數(shù)組本身可以

修改,但指向該對象或數(shù)組的地址的引用不能修改。

3.如果引用時類的成員變量,則必須當場賦值,否則編譯會報錯。

重載和重寫區(qū)別:

重載和重寫的區(qū)別

重勒發(fā)生在同一^中,方法名必須相同,參數(shù)類型不同、個數(shù)不同、順序不同,方法返回值和訪問修飾符可

以不同,發(fā)生在編譯時.

重寫:發(fā)生在父子類中,方法名、參數(shù)列表必須相同,返回值范圍小于等于父類,拋出的異常范圍小于等于父

類,訪問修畸范圖大于等于父類;如果父類方法訪問修飾符為private則子類就不能直寫該方法.

抽象類和接口

?抽象類可以存在普通成員函數(shù),而接口中只能存在publicabstract方法。

?抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是publicstaticfinal類型的。

?抽象類只能繼承一個,接口可以實現(xiàn)多個。

使用場景:當你關(guān)注一個事物的本質(zhì)的時候,用抽象類;當鯉綽■-個當作鯉嬰,用接口。

集成抽象類必須重寫里面的方法

List和Set的區(qū)別

List:有序、允許重復(fù)、可以有多個null值,支持iterator循環(huán)遍歷,或者

getlnderO獲取元素

Set:無需、不允許重復(fù)、最多有一個null值,只支持iterator遍歷數(shù)據(jù)

ArrayList和LinkList的區(qū)別

ArrayList和LinkedList區(qū)別J―-一

ArrayUst:基于動態(tài)數(shù)組,連續(xù)內(nèi)存存儲,適合下標訪問(隨機訪問),擴容機制:因為數(shù)組長度固定,超出長

度存數(shù)據(jù)時需要新建數(shù)組,然后將老數(shù)組的數(shù)據(jù)拷貝到新數(shù)組,如果不是尾部插入數(shù)據(jù)還鐘及到元素的移動(往

后短制一份,插入新元素),使用尾插法由雪初始容■可以斗大提升性能,空超過link詼大(需要創(chuàng)建大?

的node對象)—'■—

戶、入

LinkedList:基于鏈表,可以存儲在分散的內(nèi)存中,鑫做數(shù)據(jù)插入及捌碌作,曲曾直詢《箍逐一遍歷.

遍歷LinkedLis學(xué)須使用iterator不能使用for健環(huán),因為每次for?環(huán)體內(nèi)通過gel漓得某一元素時都需要對lis1重?+(

僦行靦,蹣肖耗極大.y**

另外不要試圖使用index。售返回元素索引,并利用其進行遍歷,使用indexl。網(wǎng)lis謎行了遍歷]當結(jié)果為空時會

遍歷整不列表."

HashMap和HashTable的區(qū)別以及底層實現(xiàn)

HashMap和HashTable有什么區(qū)別?其底層實現(xiàn)

是什么?

區(qū)別:

(1)HashMap方添殳有synchronized桶,百非安全,HashTable蟠安全;

(2)HashMap允許keyftjvalue為null,而HashTable不允許

2.底層實現(xiàn):數(shù)組+糙表實現(xiàn)

jdk8開始搭表高度到8、數(shù)組長度超過64,鏈表轉(zhuǎn)變?yōu)榧t黑愧,元素以內(nèi)部類Node節(jié)點存在

?計算ke和hashflfl,二次hash然后對數(shù)組長度取橫,對應(yīng)到數(shù)組下標,

?如果沒有產(chǎn)生hash沖弟下標位置沒有元素),則直接創(chuàng)建Node存入數(shù)組,

?如果產(chǎn)生hash沖突,先進行equal比較,相同則取代該元素,不同,則判斷鏈表高度播入愜表,鏈表高度達到

8,并且數(shù)組長度到64則轉(zhuǎn)變?yōu)榧t黑忸,工度低于6則將紅黑樹轉(zhuǎn)回鏈表

?key為null,存在下際0的位■

數(shù)組獷容

數(shù)組+鏈表HashMap由數(shù)組+鏈表組成的,數(shù)組是HashMap的主體,鏈表則是主要

為了解決哈希沖突而存在的,如果定位到的數(shù)組位置不含鏈表(當前entry的

next指向null),那么查找,添加等操作很快,僅需一次尋址即可;如果定位到

的數(shù)組包含鏈表,對于添加操作,其時間復(fù)雜度為0(n),首先遍歷鏈表,存在

即覆蓋,否則新增;對于查找操作來講,仍需遍歷鏈表,然后通過key對象的

equals方法逐一比對查找。所以,性能考慮,HashMap中的鏈表出現(xiàn)越少,性能

才會越好。

如何實現(xiàn)一個IOC容器

1.配置文件配置包掃描路徑

2.遞歸包掃描獲取.class文件

3.反射、確定交給I0C容器托管的類

4.對需要注入的類進行依賴注入

如何實現(xiàn)一個IOC容器

1、配置文件配置包掃描路徑

2、遞歸包掃描獲取.class文件

3、反射、確定需要交給IOC管理的類

4、對需要注入的類進行依賴注入

?配置文件中指定需要掃描的包路徑

?定義一些注解,分別表示訪問控制震、業(yè)務(wù)服務(wù)層、數(shù)據(jù)持久層、依賴注入注解、獲取配置文件注解

?從配置文件中獲取需要掃描的包路徑,獲取到當前路徑下的文件信息及文件夾信息,我們將當前路徑下所有

以.class結(jié)尾的文件添加到一個Set5S合中進行存儲

?遍歷這個set集合,獲取在類上有指定注解的類,并將其交給IOC容器,定義一個安全的Map用來存儲這些對

?遍歷這個IOC容熙,獲取到每一個莞的實例,判斷里面是有有依賴其他的類的實例,然后進行遞歸注入

字節(jié)碼是什么?帶來的好處

我們編寫的Java源碼,編譯后會生成一種.class文件,稱為字節(jié)碼文件。Java

虛擬機就是負責(zé)將字節(jié)碼文件翻譯成特定平臺下的機器碼然后運行。也就是說,

只要在不同平臺上安裝對應(yīng)的JVM,就可以運行字節(jié)碼文件,運行我們編寫的

Java程序。

編譯的結(jié)果不是生成機器碼,而是生成字節(jié)碼,字節(jié)碼不能直接運行,必須通過

JVM翻譯成機器碼才能運行。不同平臺下編譯生成的字節(jié)碼是一樣的,但是由JVM

翻譯成的機器碼卻不一樣

注意:跨平臺的是Java程序,不是JVM。JVM是用C/C++開發(fā)的,是編譯后的機

器碼,不能跨平臺,不同平臺下需要安裝不同版本的JVM.

JAVA類加載器有哪些?作用?

BootstrapclassLoader:主要負責(zé)加載核心的類庫(java.lang.*等),構(gòu)造

ExtClassLoader和APPClassLoadero

ExtClassLoader:主要負責(zé)加載jre/lib/ext目錄下的一些擴展的jar。

AppClassLoader:主要負責(zé)加載應(yīng)用程序的主函數(shù)類

雙親委派機制流程?

BootstrapCIassLoader

tms

tt

M不

s加

AppClassLoader

ClassNotFoundException

整體流程:

1.先判斷該類是否被加載過,如果沒有加載找到父類重復(fù)判斷是否加載,直到Bootstrap

加載器進行判斷,如果都沒有判斷被加載,然后往下遞歸自己是否可以加載

2.開始已經(jīng)被加載了,就不用加載了

Redis事務(wù)異常類型和觸發(fā)條件

1.編譯性異常:編譯異常就是值語法都編譯不通過,肯定是語法錯誤啦,事務(wù)

回滾。

2.運行異常:類似不同類型的數(shù)據(jù)進行賦值,事務(wù)不回滾。

Java異常體系

Java中的異常體系“八/T

Java中的所有異常都來自頂級父酒@倉>

Throwable下有兩個子避當Mgg和肛)h

Error是程序無i珊理船歌,一旦出血&錯誤,則程序?qū)⒈黄葌鱥t運行.―-

說eptiop不會導(dǎo)致好序慢生.又分為兩個部分RunTime弊eption運行時異丘在“叩ricn正女.

RunTimeExc吧cn常甯發(fā)生在延序運行過程中,會異臂序當前整執(zhí)行失;ifcFckedExcepti/贏發(fā)生在

程序贏過孱,莖導(dǎo)致程序編譯不通過.

頂級父類Throwable

倆個子類Exception和Error

Error是程序無法處理的錯誤,例如00M內(nèi)存溢出,沒有運行內(nèi)存,需要jvm調(diào)

優(yōu)

Exception不會導(dǎo)致程序停止,會導(dǎo)致當前線程執(zhí)行失敗

GC是如何判斷對象可以被回收的?

1.引用計數(shù)法,被其他對象引用計數(shù)器+1,引用釋放的時候缺點:對象相互引用,計

數(shù)器用不為o,無法回收。

2.可達性分析法。

GC如何判斷對象可以被回收

?引用計數(shù)法:每個對象有一個引用計數(shù)屬』,新增一個引用時計數(shù)加1,引用釋放時計數(shù)減1,計數(shù)為o時可以

回收,

1?可達性分析法:從GCRoois開始向下搜索,搜索所壬過的路行稱為引用鏈.當一個R急到GCRoots沿有仟

|何引用鏈相連時,則證明此對象是不可用的,那么虛擬嬴判斷是可回收對象。

1=1永玩無法於同收._______________________________________________________________________________

GCROOtS的對冢有:

?虛擬機棧(棧幀中的本地變■表)中引用的對象

?方法區(qū)中類睜態(tài)屬性引用的對象

?方法區(qū)中常量引用的對象

?本堆方法棧中JNI(即一般說的Na【ive方法)引用的對象

線程的生命周期和狀態(tài)

2.阻塞的情況又分為三種:

⑴、等待阻塞:運行的線程執(zhí)行wail方法,該線程會釋放占用的所有資源,JVM會把該線相放入?等待池”中.進入

這個狀態(tài)后,是不能自動喚醒的,必須依鼐其磔程調(diào)用notify或noUfyAII方法才能被喚醒,wait是object類的方

(2)、同步阻塞:運行的嫌在獲取對象的同步鎖時,若該同步鎖被的融占用,則JVM會把該線程放入鎖

池”中.

(3)、其他阻塞:運行的線程執(zhí)行sleep或join方法,或者發(fā)出了I/O請求時,JVM會把該線程■為阻塞狀態(tài).當

sleep狀態(tài)超時、join等待線程終止或者超時、或者I/O處理完畢時,線程更新轉(zhuǎn)入就緒狀態(tài),sleep是Thread類的

方法

1.新建狀態(tài)但三):新創(chuàng)建了一個線程對象。

2.就緒狀態(tài)(Runnable]:線程5寸象創(chuàng)建后,其硬漉調(diào)用了該對象的s【art方替.該狀態(tài)的統(tǒng)程位于可運行線程

池中,變得可運行,等需獲取CPU的使用權(quán)."

3.運行狀態(tài)(Running):就緒狀態(tài)的線程獲取了CPU,執(zhí)行程序代碼。

4.阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因為某種原因放棄CPU使用權(quán),留時停止運行.直到線程進入就緒狀

態(tài),才有機會轉(zhuǎn)到運行狀態(tài).

5.死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run方法,該線程束生命周期.

1.new新建狀態(tài)

2.就緒狀態(tài),線程對象調(diào)用start。方法,等待獲取CPU使用權(quán)

3.運行狀態(tài),線程獲取CPU資源,執(zhí)行run方法內(nèi)的代碼

4.阻塞狀態(tài),因為某種原因,釋放了CPU,停止運行,直到線程進入就緒狀態(tài),

重新競爭CPU資源

等待阻塞:線程調(diào)用了wait方法,jvm把該線程放入等待池中,不能自動喚

醒,必須依賴其他線程進行notify進行喚醒,是Object類的方法。

同步阻塞:線程獲取鎖的時候,已經(jīng)被上鎖,進入鎖池中

其他阻塞:線程執(zhí)行join或者sleep方法,sleep方法,該線程不會釋放鎖資

5.死亡狀態(tài):異常中斷,或者退出了run方法

Sleepwaityieldjoin理解

1.sleep拿到鎖之后不釋放鎖

2.Wait不設(shè)置超時時間就必須等待喚醒

3.Yield線程進入就緒狀態(tài),依然可以競爭cpu資源

4.線程加入

1、peep是Thread類的靜態(tài)李地方法,陽i型是Object類的本地方法。

2、sleep方法不會釋放lock,但是wait會釋放,而且會加入到等待隊列中.

s1eep、1f"pu$:J執(zhí)■"貨格和執(zhí)彳";,,.<一」;二」.:」.;cpy」..cpu..;

LU.cpu;:w;屋Ji-h行/?面如果si。叩時該畿程仃俊,那么sleep不會擇放這個鎮(zhèn),‘而世把鐐帶在進入,凍結(jié)狀

態(tài),也就是說其他需要這個鎖的伐程根本不可能佚取到這個鎮(zhèn).也就是說無法執(zhí)行程序.如果在睡眠期向代他畿程調(diào)用了這

個線程的interrupt。法,4;么這個線程也力拋出interruptexception抹"'1",這點制wait及?樣的.

3、sleep方法不依穎于同步器synchronized,但是wai【需要依賴synchronized關(guān)鍵字.

4、sleep不需要被喚醒(休眠之后推出阻塞),但星wait需要(不指定時間需要被別人中斷).

5、sleep一般用于當前線程休眠,或者輪循暫停操作,wail則多用于多線程之間的通信.

6、sleep會讓出CPU執(zhí)行時間且強制上下文切換,而wail則不一定,wait后可能還是有鞏會重新競爭到鎖繼續(xù)

執(zhí)行的.

yield()執(zhí)行后線程直接迸入就緒狀態(tài),馬上釋放了cpu的執(zhí)行權(quán),但是依然保留了cpu的ft行資格,所以有可能

CDU下次講行線程調(diào)電泳會i卜漢令線程獲05電im行權(quán)繼綠執(zhí)行

對線程安全的理解

對線程安全的理解就是內(nèi)存的安全,堆是內(nèi)存共享,可以被所有線程訪問

每一個線程都有自己的棧,Cpu運行的時候會上下切換棧,棧是線程安全的,沒有垃圾,不

需要gc,棧用完就彈出

對線程安全的理解

不是線程安全、應(yīng)該是內(nèi)存安全,堆是共享內(nèi)存,可以被所有線程訪問

當多個線程訪”?個對象時,如果小川進行欷外的同步控制或其他的協(xié)調(diào)操作,調(diào)用這個對望的行為都可以獲得正確的結(jié)

果,我們就說送個對象是找程安全的I

堆是進程和線程共有的空間,分全局堆和局部堆.全局堆就是所有沒有分fig的空間,局M上班5罌葭回.

堆在操作系統(tǒng)對進程初始化的時候分配,運行過程中也可以向系統(tǒng)要額外M堆,但是用完了要還給操作系統(tǒng),要不

然就是內(nèi)存泄漏.

在J.a中,堆劇ava虛擬ML所管理的內(nèi)存中最大的一塊,杲所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機啟動時gl

建。[堆所存在誦內(nèi)存區(qū)域的唯一目的就是存放對象實例,幾乎所有的對象實例以及數(shù)組都在這里分配內(nèi)存J

云界埼g1:M■以r公峭St通疝“司的三Q店室;近線程開始的時候初始化,每個線程的錢互相獨立,

因此,我是線程安全的.操作系統(tǒng)在切換線程的時候會自動切換棧.棧空間不需要在離級語言里面顯式的分配和釋

放.

目前主流操作系統(tǒng)都是多任務(wù)的,即多個進程同時運行.為了保證安全,每個進程只畿訪問分8貽自己的內(nèi)存空

間,而不能訪問別的進程的,這是由操作系統(tǒng)保障的.

在毋個進程時內(nèi)存空間中都會有一塊特姝的公區(qū)區(qū)域,通常稱內(nèi)堆(內(nèi)仔).進程內(nèi)的所自選槎都OJ以訪I可到餒區(qū)

域,這就是造成問題的潛在原因.

什么事守護線程

對守護線程的理解

I

守護線程:為所有非守護線程提供服分的線程;任何一個守護線程都是整個JVM中所有非守滬線程的保姆;

守護線程類似于整個進程的一個默默無聞的小嘍嘍;它的生死無關(guān)重要,它卻依賴整個進程而運行;哪天其頓程

結(jié)束了,沒有要執(zhí)行的了,程序就結(jié)束了,理都沒理守護線程,就把它中斷了;

注意:由于守護線程的終止是自身無法控制的,因此千萬不要把10、File等重要操作邏輯分配給它;因為它不靠

譜;

GC垃圾回收線程,典型的守護線程

Threadlocal的使用場景和原理

ThreadLocal的原理和使用場景

每~介Thread對象均含有一個ThreadLocalMap類型的成員變量threadLocals,它存儲本比程中所有

ThreadLocal對象及其對應(yīng)的值1

ThreadLocalMap由一個■個Entry對象為成

Entry繼承自weakReference<ThreadLoca1v?>>,一個Entry由ThreadLocal對象和Object構(gòu)成.由此可

見,Entry的key息ThreadLocal對象,并且是一個弱引用.當沒指向keyfi9強引用后,該key就會被垃圾收集器回

當執(zhí)行set方法時,ThreadLocal首先會獲取當前線程對象,然后獲取當前線程的ThreadLocalMap對象.再以當前

ThreadLocal對象為key,將值存fifi^ThreadLocalMap對象中.

get方法執(zhí)行Q程類似.ThreadLocal苜光會獲取當前線程對象,然后獲取當前線程的ThreadLocalM叩對象.再以

當所hreadLocal對象為key,應(yīng)協(xié)alue.

由于每一條線程均含有名自私商的Thre2dsealMap容88,這些容即相互獨立互不影響,因此不會存在線程安全性

問題,從而也無需使用同步機制來保證多條線程訪問容疆的互斥性.

使用場景:

1、在進行對象跨層傳遞的時候,使用ThreadLocal可以避免多次傳遞,打破層次間的約束.1

2、線程間數(shù)據(jù)隔離

3、進行事務(wù)操作,用于存儲線程事箔信息。

4、數(shù)據(jù)庫連接,Session會話管理。

為每一個線程提供變量副本

ThreadLocal的實現(xiàn)原理,每一個Thread維護一個ThreadLocalMap,key為使用S5弓I用的ThreadLocal實例,

value為線程變量的副本

〃可以拋出異常.仃返回值

classTask(

//①逋過匿名內(nèi)部類亂源ThreadLocal的initialValue()方法,指定初始值

privatestaticThreadLocal<Integer>seqNum=ThreadLocal.withlnitial^)-

//②獲取F?個序列值

publicintgetNextNum(){

seqNum.set(seqNum.get0+1);

returnseqNum.get。;

)

publicvoidtest(){

for(int1=0;i<3;i++){

System.out.printIn(Thread.current77)read().getName()+getNextNum())

)

)

Threadlocal內(nèi)存泄露,如何避免

Threadlocalkey為弱引用,線程結(jié)束就被GC回收,value為強引用,不會被回收,

造成key為null,value無法刪除的情況。Key為當前線程

因此,Throcdlcral內(nèi)存泄漏的根源是:由士工hreadlcralMap的生命周期跟Thread一樣長.如果沒有手動刪除對

應(yīng)key就會導(dǎo)致內(nèi)存泄漏,而不是因為弱引用.--

ThreadLocal正確的使用方法

憚次使用完ThreadLocal都調(diào)用它的remove。方法消除數(shù)更

(?將ThreadLocal變量定義成叩vgiesialic.這樣就一直存在ThreadLocal的強弓I用.也壁憑證任何時候都能

通過ThreadLocal吧易引用訪問到Entry的valuefg,進而清除掉."

避免:

每次使用完remover方法

變量定義privatestatic,改為強引用

并發(fā)、并行、串行的區(qū)別

?!?u4

并發(fā)、并行、串行的區(qū)別°內(nèi)

串行在時間上不可能發(fā)生重疊,前一夕壬務(wù)沒搞定,下一個任務(wù)就只能等著(

并行在時間上是重疊的,兩個任務(wù)在同一時刻互不干擾的同時執(zhí)行。

并發(fā)允許兩個任^彼此干擾。統(tǒng)一時間點、只有一個任務(wù)運行,交替執(zhí)行

?

并行時間重疊,可以同一時刻一起執(zhí)行

并發(fā)通過時刻只有一個任務(wù)運行,交替運行,充分利用CPU資源

并發(fā)的三大特性

原子性、可見性、有序性

1.原子性

含義

一個或多個操作,要么全部執(zhí)行且在執(zhí)行過程中不被任何因素打斷,要么全部不

執(zhí)行。

在Java中,對基本數(shù)據(jù)類型的變量的讀取和賦值操作是原子性操作。

重要

不采取任何的原子性保障措施的自增操作并不是原子性的。

如何保證原子性

?通過synchronized關(guān)鍵字定義同步代碼塊或者同步方法保障原子性。

?通過Lock接口保障原子性。

.通過Atomic類型保障原子性。

2.可見性

含義

當一個線程修改了共享變量的值,其他線程能夠看到修改的值。

Java內(nèi)存模型是通過在變量修改后將新值同步回主內(nèi)存,在變量讀取前從主內(nèi)

存刷新變量值這種依賴主內(nèi)存作為傳遞媒介的方法來實現(xiàn)可見性的。

volatile變量和普通變量區(qū)別

普通變量與volatile變量的區(qū)別是volatile的特殊規(guī)則保證了新值能立即

同步到主內(nèi)存,以及每次使用前立即從主內(nèi)存刷新,因此我們可以說volatile

保證了多線程操作時變量的可見性,而普通變量則不能保證這一點。

如何保證可見性

?通過volatile關(guān)鍵字標記內(nèi)存屏障保證可見性。

?通過synchronized關(guān)鍵字定義同步代碼塊或者同步方法保障可見性。

?通過Lock接口保障可見性。

?通過Atomic類型保障可見性。

?通過final關(guān)鍵字保障可見性

3.有序性

含義

即程序執(zhí)行的順序按照代碼的先后順序執(zhí)行。

JVM存在指令重排,所以存在有序性問題。

如何保證有序性

?通過synchronized關(guān)鍵字定義同步代碼塊或者同步方法保障可見性。

?通過Lock接口保障可見性。

?Volatile關(guān)鍵字,設(shè)置內(nèi)存屏障,防止指令重排

什么是線程池?線程參數(shù)解釋

線程池,threadpool,是一種線程使用模式,線程池維護著多個線程,等待著

監(jiān)督管理者分配可并發(fā)執(zhí)行的任務(wù)。

三個方法(單一線池,固定線池,緩存線池)

*七個參數(shù)

通過設(shè)置corepoolsize和maxmumpoolsize來構(gòu)造不同的線程池

七大參數(shù):

核心線程池

最大線程池

心跳

時間

等待隊列

線程池工廠

拒絕策略

publicThreadPoolExecutor(intcorePoolSize,

intmaximumPoolSize,

longkeepAliveTime,

TimeUnitunit,

BlockingQueue<Runnable>workQueue,

ThreadFactorythreadFactory,

RejectedExecutionHandlerhandler){

使用線程池的好處:

1、降低資源消耗;提高線程利用率,降低創(chuàng)建和銷毀線程的消耗。

2、提高響應(yīng)速度;任務(wù)來了,直接有線程可用可執(zhí)行,而不是先創(chuàng)建線程,再執(zhí)行。

3、提高線程的可管理性;線程是稀缺資源,使用線程池可以統(tǒng)一分配調(diào)優(yōu)監(jiān)控。

提高線程復(fù)用,監(jiān)控和管理

線程池處執(zhí)行流程

線程池阻塞隊列的作用?為什么要先添加到阻塞隊列而不

是直接創(chuàng)建最大線程?

I

1、一般的隊列只能保證作為一個有限長度的埴沖區(qū),如果超出了緩沖長度,就無法保卬當前的任務(wù)了,阻塞隊列

通過阻塞可以保留住當前想要繼續(xù)入隊的任務(wù).

阻塞隊列可以保證任務(wù)隊列中沒有任務(wù)時陽惠獲取任務(wù)的線程,使得線程進入wail狀態(tài),釋放cpu資源.

阻塞隊列自帶用塞和唉醒的功能,不需要幼枚b理,無任務(wù)執(zhí)行時,境程池利用阻塞隊列的take方法掛起,從而維

持核心線程的存活、不至于一直占用cpu資源

2、在創(chuàng)建新線程的時候,是要獲取全局談的,這個時候反它的就得阻塞,影響了整體效率.

就好比一位業(yè)里面有10個(core)正式工的名額,最多招10個正式工,要是任務(wù)超過正式工A數(shù)(task,

core)的情況下,工廠領(lǐng)導(dǎo)(線程池)不是苜先擴招工人,還是這10人,但是任務(wù)可以稍微積壓一下,即先放到

隊列去(代價低)?正式工慢1肝,遲早會干完的,要是任務(wù)還在繼續(xù)增加,超過正式工B9加班忍耐極限了

(隊列滿了),就的招外包幫忙了(注意是臨時工)要是正式工力口上外包還是不能完成任務(wù),目斷來的任務(wù)就會被

領(lǐng)導(dǎo)拒絕了(線程池的拒絕策略).

創(chuàng)建線程的時候要獲取全局鎖,其他線程和會阻塞

線程池實現(xiàn)復(fù)用的原理

同一個線程可以從阻塞隊列里不斷獲取新的任務(wù)進行執(zhí)行,對Thread進行了封裝,擺渡了

一個線程必須對應(yīng)一個任務(wù)的限制。并不是每次執(zhí)行都會調(diào)用start方法,通過循環(huán)任務(wù)進

行任務(wù)斷定

線程池中線程復(fù)用原理…一'1nd

線程池將線程和任務(wù)進行解耦,線程是里呈,任務(wù)是任務(wù).擺脫了之前通過Thread創(chuàng)建線程時的一個線程必

須對應(yīng)一令壬務(wù)的限制。"

在線程池中,同一個線程可以從阻塞隊列中不斷獲取新任芬來執(zhí)行,其核心原理在于線程池對Thread迸行了

封裝,并不「每次執(zhí)行任務(wù)都會調(diào)踵reads1吧)來創(chuàng)建新線程,而是在每個線程去執(zhí)行一個“循環(huán)任務(wù)",在這

個“循林任務(wù)"中不停檢便是合句銬標被執(zhí)行一茹果有則卸妾執(zhí)行.也塞遇出住若中的耍印去,將run萬

法當成一個普通的方法執(zhí)行,通過這種方式只使用固定的線程就將所有任芬的「孟方法串底繇:

集合都不安全

方法沒有用synoitt包裹,多線程情況下使用C。八C〃K七八土提供的類型保證線程

安全

Lis僅StH八g〉list=MWCopy。八WriteArr〃gList<>0;

Se僅String〉set=CoZecttocs.sg八ckKoniNedSeWnewHaskSet<>0);//方

法工.并發(fā)安全

Map<S±HngQbject〉set-MwC。八c“”C八±H〃skM即<>();

Cabbleable和runnable的區(qū)另U

i.可以有返回值

為2.可以拋出異常

//FutureTask是Ru八八〃詠接口的實現(xiàn)類,坐中間商使用,起連接作用,因

為處理的是ruiaable接口

FutureTaskfutureTask-MwFutureTask(callableTestl-);

2.

生產(chǎn)者消費者問題

六字核心判斷等待業(yè)務(wù)通知喚醒

Condition的作用

C?!?加M取代了對象監(jiān)視器的使用,優(yōu)點:可以實現(xiàn)精確喚醒線程

實現(xiàn)線程通信,取代了wait和notif,可以實現(xiàn)精準喚醒

線程資源類的作用

資源類,降低耦合,線程處理資源類

CountDownLatch

初始化線程個數(shù)

coc(八tDow八Latch.cou八tDow八();//減一

c?!鞍藅DownLatch.await。;〃等待計數(shù)器歸零,在執(zhí)行后面操作

CyclicBarrier

線程數(shù)量自增一

*CyclicBarrier線程數(shù)時H增一

*

*力/

publicclassCyclicBarrierTest{

?//舉例?七個線程集齊七個龍珠,不喚神龍

publicstaticvoidmain(String[]args){

〃線程數(shù)達到指定個數(shù),執(zhí)行參數(shù)電血的線程

CyclicBarrierCyclicBarrier=newCyclicBarrier(parties8,newThread(()

System.out.printing'召喚神龍,許愿“);

},name:"悟空"));

for(inti=1;i<=7;i++){

finalinttemp=i;

newThread(()-><

System.out.printin("集齊第"+temp+"顆龍珠");

try{

cyclicBarrier.await();“加線程數(shù)

Semaphore

Scj/vxapkoira信號量處理并發(fā)

*類似搶車位行為處理并發(fā)問題

ReadWriteLock讀寫鎖細粒度

同時只有一個線程去進行寫操作(保證原子性)

同時可以有多個線程去進行讀操作

獨占領(lǐng)(寫鎖)保證原子性

共享鎖(讀鎖)

BlockingQueue阻塞隊列

并阻塞隊列有四種阻塞處理機制(隊列存取數(shù)據(jù)采用的方法不同,就是不同的

處理策略)

興工.拋出異常(阻塞拋異常)

共2.有返回值,不拋異常(有Boolca八返回值)

殺3.阻塞等待(一直等,不拋異常)

*4.超時等待(超時結(jié)束,不拋異常)

四個拒絕策略

MWThreadPoo/ExecutorAbortPolicyO//不處理,拋出異常

*MWTlareadPoolExecutor.CallerRb(ia$Policy()//哪里來的回哪里去

newTTareadPoolExecutor.PiscardPolicyC)f丟棄任務(wù),

不會拋出異常

*M\A/ThreadPoo/Executor.DiscardOlde$tPoticy()//隊列滿了,嘗試

與最早的線程競爭,

四大函數(shù)式接口

〃函數(shù)式接口編程C。仲2只有參數(shù)沒有返回值

//函數(shù)式接口Function有一"個傳入?yún)?shù),有一個傳出參數(shù)

//斷定性接口,一個傳入?yún)?shù)類型,boolean返回值

//Sapph'eK供給性接口,沒有參數(shù),只有返回值

Volatile關(guān)鍵字作用

工.保證可見性(每個線程都有自己的工作空間,數(shù)據(jù)從內(nèi)存中讀取,可能未及時

更新數(shù)據(jù))

興2.不保證原子性(如果要保證原子性,可以使用原子性類去創(chuàng)建對應(yīng)數(shù)據(jù)類型)

興二避免指令重排(設(shè)置前后內(nèi)存屏障,禁止指令重排)

單列模式

餓漢式

餓漢式單例(線程安全)

*一開始就創(chuàng)建

共優(yōu)點:這種寫法比較簡單,就是在類裝載的時候就完成實例化。避免了線程

同步問題。

缺點:在類裝載的時候就完成實例化,沒有達到LazgLoadi八g的效果。如

果從始至終從未使用過這個實例,則會造成內(nèi)存的浪費。

publicclassHungry{

privateintage;

privateStringname;

privatefinalstaticHungryhungry=newHungry();

nriVAtAMlinar

)

IpublicstaticHungrygetlnstance(){returnhungry;}

publicHungry(intage,Stringname){

this.age=age;

this.name=name;

)

懶漢式

方式一(不安全,if只判斷一次,可能同時有多個線程去執(zhí)行)

/*

*懶漢式(線程不安全):

*使用在創(chuàng)建

★*/

publicclassLazyTestl(

privatestaticLazyTestllazyTest!;

privateLazyTestl(){};

publicstaticLazyTestlgetlnstance(){

多線程卜..可能多個線程經(jīng)過if判斷,創(chuàng)建個對?實例|

lazyTest1-neviLazyTestl();

)

returnlazyTestl;

I

}

方式二添加sg八chnmized鎖

?WI-9

/*

*懶漢式(線程安全,效率太低,不推薦使用):

*使用在創(chuàng)建

★*/

publicclassLazyTest2(

privatestaticLazyTest2lazyTest!;

privateLazyTest2(){};

//添加synchronized鎖,線程安全,效率低,每?次執(zhí)行都要獲取鎖

publicstaticsynchronizedLazyTest2getlnstance(){

if(lazyfest7==null){

lazyTest1=ne^LazyTest2();

}

returnlazyTest!;

}

)

方式三雙重檢測機制

/*

*雙垂檢索,推薦使用,線程安全,效率商)

飛〃

publicclassLazyTest3{

“volatile關(guān)鍵字,防止指令肅排J

privatestaticvolatileLazyTest3lazyTest!;

LazyTest3()(};

publicstaticLazyTest3getlnstance(){

if(lazyfest7==null){-

〃鎖住類模板.同?個時刻只有?個線程獲取鎖然后創(chuàng)建對您.只執(zhí)彳f?次即可,效乎消

synchronized(LazyTest3.class){

if(Iazyrest/==null){

lazylest7=newLazyTest3();

)

)

)

returnlazyTestl;

}

)

方式四枚舉

packagecom.tql.test_13;MS八

/*

*借助JDK1.5中添加的枚舉來實現(xiàn)單例模式.不僅能避免多線程同步問題?而11還能防止反序列化成新、

p*/

publicenumLazyTe|st4(

Instance;

publicvoidgetlnstance(){}

)

枚舉為什么是線程安全的

我們定義的一個枚舉,在第一次被真正用到的時候,會被虛擬機加載并初始化,

而這個初始化過程是線程安全的。而我們知道,解決單例的并發(fā)問題,主要解決

的就是初始化過程中的線程安全問題。

所以,由于枚舉的以上特性,枚舉實現(xiàn)的單例是天生線程安全的。

普通類的反序列化是通過反射實現(xiàn)的,枚舉類的反序列化不是通過反射實現(xiàn)的。

所以,枚舉類也就不會發(fā)生由于反序列化導(dǎo)致的單例破壞

可重入鎖概念

*synchronized鎖獲取外面的鎖自動獲取里面的鎖

共lock鎖要配對出現(xiàn)(上鎖,就要解鎖)

ReentrantLock和synchronized不一樣,需要手動釋放鎖,所以使用ReentrantLock的時候一定要

手動釋放鎖,并IL加鎖次數(shù)和釋放次數(shù)要一樣

如何解決死鎖問題

(互相抱有對方的資源不釋放)

興工.互斥條件:一個資源每次只能被一個進程使用;

2.請求與保持條件:個進程因請求資源而阻塞時,對已獲得的資源保持不放;

二不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪;

4.循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系;

Spring是什么

spring是什么?

輕量級的開源的J2EE框架.它是一個容器框架,用來裝javabean(java對象),中間層框架(萬能膠)可以起一

個連接作用,比如說把Strutsffihibernate粘合在一起運用,可以讓我們的企業(yè)開發(fā)更快、更簡潔

Spring是一個輕量級的控制反轉(zhuǎn)(loC廂面向切面(AOP)的容88框架

-從大小與開銷兩方面而言Spring都是輕量級的。

--通過控制反轉(zhuǎn)(I。。的技術(shù)達到松燃合的目的

-提供了面向切面編程的豐富支持,允許通過分離應(yīng)用的業(yè)務(wù)邏輯與系統(tǒng)級服務(wù)進行內(nèi)聚性的開發(fā)

-包含并管理應(yīng)用對象(Bean)的配置和生命周期,這個意義上是一個容器.

--將簡單的組件配置、組合成為復(fù)雜的應(yīng)用,這個意義上是一個框架.

I

AOP理解

橫向切面,對系統(tǒng)功能進行增強,如日志、事務(wù)讓關(guān)注點代碼與業(yè)務(wù)邏輯代碼分

離面向切面編程,通過預(yù)編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的

一種技術(shù)。AOP是OOP的延續(xù),是軟件開發(fā)中的一個熱點,也是Spring框架中

的一個重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對業(yè)務(wù)邏輯的

各個部分進行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可

重用性,同時提高了開發(fā)的效率。

13*RAspect:指定當前類為切面類

14*/

15?Component〃加入到IoC容器

16?Aspect〃指定節(jié)將類為切面類

17publicclassAop{

18

19

20//gPointcut("execution(*com.bi?.aop.UserDao.save(..))")..代表所行參數(shù)

21//gPointcut("execution(,com.bie.aop.UserDao.*())")指定所右的方法

22//gPointcut("execution(*com.bie.aop.UserDao.save())")指定save方法

23

@Pointcut("execution(,com.bie.aop.UserDao.*(..))")

25publicvoidpointcut(){

26

271

28

29@Before("pointcut()")

30publicvoidbegin(){

System.out.printIn("JFA'!T^");

32}

33

34?After("pointcut()")

35publicvoidclose(){

System.out.printin;

37}

38

39}

如果ioc是處理解耦的話,那么aop就是來提升內(nèi)聚的

IOC理解(控制反轉(zhuǎn))

對象由spring容器去創(chuàng)建和注入,不需要程序要去手動創(chuàng)建,就是控制翻轉(zhuǎn)。實

現(xiàn)低耦合

依賴注入:

'蒙得依賴對象的過程被反轉(zhuǎn)了%控制被反轉(zhuǎn)之后,獲得礴對象的過程由自身管理變?yōu)榱擞蒳oc容器主動注入.

依賴注入是實現(xiàn)IOC的方法,就是由IOC容器在運行期間,動態(tài)地將某種依賴關(guān)系注入到對象之中.

Bean的作用域

解釋下Spring支持的幾種bean的作用域。J5/

?singleton:默認,每個容黯中只看一個bean的實例,單例的橫式由BeanFaaorv自身來維護.該對象的生命

周期是與SpringIOC容器一致的,:但在第一次被注入時才會創(chuàng)建)?J''

?prouxje:為受二個bean請求提供一個實例.在每次注入時都會創(chuàng)建一個新的龍象

?requestbean被定義為在每個HTTP請求中創(chuàng)建一個單例對象,也就是說在單個請求中都會復(fù)用這一單例

?oSC過皿-與request范圍類似,確保每個session中有一^bean的實照在session過期后,bean會隨之失

城~

?叩plicalion:bean被定義為在SeMeiContext的生命周期中復(fù)用一個單例對象.

?websocket:bean被定義為在websocket的生命周期中復(fù)用一個單例對象.

global-session:全局作用域,global-session和Porilei應(yīng)用相關(guān).當你的應(yīng)用部署在PorUei容需中工作時,

它包含很多porile【.如果你想要聲明讓所有的porUe【共用全局的存儲變■的話,那么這全局變量需要存儲在

global-session中。全局作用域與Servlei中的session作用域效果相同。

spring框架中的bean是線程安全的嗎

Bean默認是單例模式

存儲數(shù)據(jù)不安全推薦ThreadLocal

不存儲數(shù)據(jù)安全

Spring框架采用了那些設(shè)計模式和應(yīng)用場景?

動態(tài)代理模式

簡單工廠模式

適配器模式

單例模式

工廠模式

觀察者模式

策略模式

Spring實現(xiàn)事務(wù)方式和隔離級別

實現(xiàn)方式基于編程式或者基于注解@Transaction

隔離級別:

讀未提交(臟讀、不可重復(fù)度、幻讀)

讀已提交(不可重復(fù)度、幻讀)

可重復(fù)讀(幻讀)

串行化

KE)褶式9)視解M主也⑴?M(tD

Spring事務(wù)的實現(xiàn)方式和原理以及隔離級別?

在使用Spring框架時,可以有兩種使用事分的方式,一種是編程式的,一種是申明式的,@Transactional注解就

是申明式的。

首先,事芬這個概念是數(shù)據(jù)庫層面的,Sprin卿是基于數(shù)據(jù)庫中的事務(wù)進行了擴展,以及提供了一些能讓程序員更

加方便操作事芬的方式.

比如我們可以通過在某個方法上增加@一9(1乳3。M1注解,就可以開啟事務(wù),這個方法中所有的sql都會在一個事

務(wù)中執(zhí)行,統(tǒng)一成功或失敗。

在f方法上加了@Transaciional注解后,Spring會基于這個類生成一個代理對象,會將這個代理對象作為

bean,當在使用這個的對象的方法時,如果這個方法上存在@Transaaional注解,那么代理邏輻會先把事務(wù)的

自動提交設(shè)■為false,然后再去執(zhí)行原本的業(yè)務(wù)邏輯方法,如果執(zhí)行業(yè)務(wù)邏輯方法沒有出現(xiàn)異常,那么代理邏輯

中就會將事務(wù)進行提交,如果執(zhí)行業(yè)若建輯方法出現(xiàn)了異常,那么則會將事多進行回潦.

當然,針對哪些異?;貪L事芬是可以配■的,可以利用@Transaaional注解中的rollbackFor屬性進行配置,默認

情況下會對RunUmeExcepHon和Error進行回流.

spring事務(wù)隔離級別就是數(shù)據(jù)庫的隔離級別:外加一個默認級別

?readuncommitted(未提交讀)

?readcommitted(提交讀、不可窗復(fù)讀)

?repeatableread(可康復(fù)讀)

?sriali7口hip由衿生\

spring事務(wù)什么時候會失效

事務(wù)是基于AOP進行實現(xiàn)的,生成bean代理對象注入到容器中,使用事務(wù)必須

從容器中獲取,不然不起作用

1.自調(diào)用,不可以使用this去調(diào)用,this對象不是代理對象

2.方法修飾符不是public

3.沒有注入到bean容器中

4.數(shù)據(jù)庫不支持事務(wù)

spring事務(wù)什么時候會失效?

springW?09JRMAOP,進行7切面喇,那么失效的根本原因JB這個AOP不起作用力對見情況存如下幾種

1、型自調(diào)用,類里面使用(his學(xué)用本類的方法([his通常丘略)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論