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

史上最強多線程面試44題和答案:線程鎖+線程池+線程同步等

  發(fā)布時間:2019-08-06 16:11:40   作者:AI喬治   我要評論
這篇文章主要介紹了史上最強多線程面試44題和答案:線程鎖+線程池+線程同步等,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

1、并發(fā)編程三要素?

1)原子性
原子性指的是一個或者多個操作,要么全部執(zhí)行并且在執(zhí)行的過程中不被其他操作打斷,要么就全部都不執(zhí)行。
2)可見性
可見性指多個線程操作一個共享變量時,其中一個線程對變量進行修改后,其他線程可以立即看到修改的結(jié)果。
實現(xiàn)可見性的方法:
synchronized或者Lock:保證同一個時刻只有一個線程獲取鎖執(zhí)行代碼,鎖釋放之前把最新的值刷新到主內(nèi)存,實現(xiàn)可見性。
3)有序性
有序性,即程序的執(zhí)行順序按照代碼的先后順序來執(zhí)行。

2、多線程的價值?

1)發(fā)揮多核CPU的優(yōu)勢
多線程,可以真正發(fā)揮出多核CPU的優(yōu)勢來,達到充分利用CPU的目的,采用多線程的方式去同時完成幾件事情而不互相干擾。
2)防止阻塞
從程序運行效率的角度來看,單核CPU不但不會發(fā)揮出多線程的優(yōu)勢,反而會因為在單核CPU上運行多線程導致線程上下文的切換,而降低程序整體的效率。但是單核CPU我們還是要應用多線程,就是為了防止阻塞。試想,如果單核CPU使用單線程,那么只要這個線程阻塞了,比方說遠程讀取某個數(shù)據(jù)吧,對端遲遲未返回又沒有設置超時時間,那么你的整個程序在數(shù)據(jù)返回回來之前就停止運行了。多線程可以防止這個問題,多條線程同時運行,哪怕一條線程的代碼執(zhí)行讀取數(shù)據(jù)阻塞,也不會影響其它任務的執(zhí)行。
3)便于建模
這是另外一個沒有這么明顯的優(yōu)點了。假設有一個大的任務A,單線程編程,那么就要考慮很多,建立整個程序模型比較麻煩。但是如果把這個大的任務A分解成幾個小任務,任務B、任務C、任務D,分別建立程序模型,并通過多線程分別運行這幾個任務,那就簡單很多了。

3、創(chuàng)建線程的有哪些方式?

1)繼承Thread類創(chuàng)建線程類
2)通過Runnable接口創(chuàng)建線程類
3)通過Callable和Future創(chuàng)建線程

4.創(chuàng)建線程的三種方式的對比?

1)采用實現(xiàn)Runnable、Callable接口的方式創(chuàng)建多線程。
優(yōu)勢是:
線程類只是實現(xiàn)了Runnable接口或Callable接口,還可以繼承其他類。
在這種方式下,多個線程可以共享同一個target對象,所以非常適合多個相同線程來處理同一份資源的情況,從而可以將CPU、代碼和數(shù)據(jù)分開,形成清晰的模型,較好地體現(xiàn)了面向?qū)ο蟮乃枷搿?br /> 劣勢是:
編程稍微復雜,如果要訪問當前線程,則必須使用Thread.currentThread()方法。
2)使用繼承Thread類的方式創(chuàng)建多線程
優(yōu)勢是:
編寫簡單,如果需要訪問當前線程,則無需使用Thread.currentThread()方法,直接使用this即可獲得當前線程。
劣勢是:
線程類已經(jīng)繼承了Thread類,所以不能再繼承其他父類。
3)Runnable和Callable的區(qū)別

  • Callable規(guī)定(重寫)的方法是call(),Runnable規(guī)定(重寫)的方法是run()。
  • Callable的任務執(zhí)行后可返回值,而Runnable的任務是不能返回值的。
  • Call方法可以拋出異常,run方法不可以。
  • 運行Callable任務可以拿到一個Future對象,表示異步計算的結(jié)果。它提供了檢查計算是否完成的方法,以等待計算的完成,并檢索計算的結(jié)果。通過Future對象可以了解任務執(zhí)行情況,可取消任務的執(zhí)行,還可獲取執(zhí)行結(jié)果。

5、線程的狀態(tài)流轉(zhuǎn)圖

線程的生命周期及五種基本狀態(tài):

Java線程具有五中基本狀態(tài)
1)新建狀態(tài)(New):當線程對象對創(chuàng)建后,即進入了新建狀態(tài),如:Thread t = new MyThread();
2)就緒狀態(tài)(Runnable):當調(diào)用線程對象的start()方法(t.start();),線程即進入就緒狀態(tài)。處于就緒狀態(tài)的線程,只是說明此線程已經(jīng)做好了準備,隨時等待CPU調(diào)度執(zhí)行,并不是說執(zhí)行了t.start()此線程立即就會執(zhí)行;
3)運行狀態(tài)(Running):當CPU開始調(diào)度處于就緒狀態(tài)的線程時,此時線程才得以真正執(zhí)行,即進入到運行狀態(tài)。注:就 緒狀態(tài)是進入到運行狀態(tài)的唯一入口,也就是說,線程要想進入運行狀態(tài)執(zhí)行,首先必須處于就緒狀態(tài)中;
4)阻塞狀態(tài)(Blocked):處于運行狀態(tài)中的線程由于某種原因,暫時放棄對CPU的使用權,停止執(zhí)行,此時進入阻塞狀態(tài),直到其進入到就緒狀態(tài),才 有機會再次被CPU調(diào)用以進入到運行狀態(tài)。根據(jù)阻塞產(chǎn)生的原因不同,阻塞狀態(tài)又可以分為三種:
1.等待阻塞:運行狀態(tài)中的線程執(zhí)行wait()方法,使本線程進入到等待阻塞狀態(tài);
2.同步阻塞 — 線程在獲取synchronized同步鎖失敗(因為鎖被其它線程所占用),它會進入同步阻塞狀態(tài);
3.其他阻塞 — 通過調(diào)用線程的sleep()或join()或發(fā)出了I/O請求時,線程會進入到阻塞狀態(tài)。當sleep()狀態(tài)超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉(zhuǎn)入就緒狀態(tài)。
5)死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期。

6.什么是線程池? 有哪幾種創(chuàng)建方式?

線程池就是提前創(chuàng)建若干個線程,如果有任務需要處理,線程池里的線程就會處理任務,處理完之后線程并不會被銷毀,而是等待下一個任務。由于創(chuàng)建和銷毀線程都是消耗系統(tǒng)資源的,所以當你想要頻繁的創(chuàng)建和銷毀線程的時候就可以考慮使用線程池來提升系統(tǒng)的性能。
java 提供了一個 java.util.concurrent.Executor接口的實現(xiàn)用于創(chuàng)建線程池。
四種線程池的創(chuàng)建:
(1)newCachedThreadPool創(chuàng)建一個可緩存線程池
(2)newFixedThreadPool 創(chuàng)建一個定長線程池,可控制線程最大并發(fā)數(shù)。
(3)newScheduledThreadPool 創(chuàng)建一個定長線程池,支持定時及周期性任務執(zhí)行。
(4)newSingleThreadExecutor 創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務。

7.線程池的優(yōu)點?
1)重用存在的線程,減少對象創(chuàng)建銷毀的開銷。
2)可有效的控制最大并發(fā)線程數(shù),提高系統(tǒng)資源的使用率,同時避免過多資源競爭,避免堵塞。
3)提供定時執(zhí)行、定期執(zhí)行、單線程、并發(fā)數(shù)控制等功能。

8.Java中的同步集合與并發(fā)集合有什么區(qū)別?

同步集合類:

  • Vector
  • Stack
  • HashTable
  • Collections.synchronized方法生成

并發(fā)集合類:

  • ConcurrentHashMap
  • CopyOnWriteArrayList
  • CopyOnWriteArraySet等

9.同步集合與并發(fā)集合的區(qū)別

同步集合與并發(fā)集合都為多線程和并發(fā)提供了合適的線程安全的集合,不過并發(fā)集合的可擴展性更高。同步集合比并發(fā)集合會慢得多,主要原因是鎖,同步集合會對整個May或List加鎖,而并發(fā)集合例如ConcurrentHashMap,
把整個Map 劃分成幾個片段,只對相關的幾個片段上鎖,同時允許多線程訪問其他未上鎖的片段(JDK1.8版本底層加入了紅黑樹)。

10.常用的并發(fā)工具類有哪些?

  • CountDownLatch
  • CyclicBarrier
  • Semaphore
  • Exchanger

11.CyclicBarrier和CountDownLatch的應用場景?

CountDownLatch : 一個線程(或者多個), 等待另外N個線程完成某個事情之后才能執(zhí)行。 CyclicBarrier : N個線程相互等待,任何一個線程完成之前,所有的線程都必須等待。
CountDownLatch的使用場景:
在一些應用場合中,需要等待某個條件達到要求后才能做后面的事情;同時當線程都完成后也會觸發(fā)事件,以便進行后面的操作, 這個時候就可以使用CountDownLatch。
CyclicBarrier 使用場景
CyclicBarrier可以用于多線程計算數(shù)據(jù),最后合并計算結(jié)果的應用場景。

12.CyclicBarrier和CountDownLatch的區(qū)別

1)CountDownLatch簡單的說就是一個線程等待,直到他所等待的其他線程都執(zhí)行完成并且調(diào)用countDown()方法發(fā)出通知后,當前線程才可以繼續(xù)執(zhí)行。
2)cyclicBarrier是所有線程都進行等待,直到所有線程都準備好進入await()方法之后,所有線程同時開始執(zhí)行!
3)CountDownLatch的計數(shù)器只能使用一次。而CyclicBarrier的計數(shù)器可以使用reset() 方法重置。所以CyclicBarrier能處理更為復雜的業(yè)務場景,比如如果計算發(fā)生錯誤,可以重置計數(shù)器,并讓線程們重新執(zhí)行一次。
4)CyclicBarrier還提供其他有用的方法,比如getNumberWaiting方法可以獲得CyclicBarrier阻塞的線程數(shù)量。isBroken方法用來知道阻塞的線程是否被中斷。如果被中斷返回true,否則返回false。

13.synchronized的作用?

在Java中,synchronized關鍵字是用來控制線程同步的,就是在多線程的環(huán)境下,控制synchronized代碼段不被多個線程同時執(zhí)行。
synchronized既可以加在一段代碼上,也可以加在方法上。

14.volatile關鍵字的作用

對于可見性,Java提供了volatile關鍵字來保證可見性。
當一個共享變量被volatile修飾時,它會保證修改的值會立即被更新到主存,當有其他線程需要讀取時,它會去內(nèi)存中讀取新值。
從實踐角度而言,volatile的一個重要作用就是和CAS結(jié)合,保證了原子性,詳細的可以參見java.util.concurrent.atomic包下的類,比如AtomicInteger。

15.什么是CAS

CAS是compare and swap的縮寫,即我們所說的比較交換。
cas是一種基于鎖的操作,而且是樂觀鎖。在java中鎖分為樂觀鎖和悲觀鎖。悲觀鎖是將資源鎖住,等一個之前獲得鎖的線程釋放鎖之后,下一個線程才可以訪問。而樂觀鎖采取了一種寬泛的態(tài)度,通過某種方式不加鎖來處理資源,比如通過給記錄加version來獲取數(shù)據(jù),性能較悲觀鎖有很大的提高。
CAS
操作包含三個操作數(shù) ——
內(nèi)存位置(V)、預期原值(A)和新值(B)。如果內(nèi)存地址里面的值和A的值是一樣的,那么就將內(nèi)存里面的值更新成B。CAS是通過無限循環(huán)來獲取數(shù)據(jù)的,若果在第一輪循環(huán)中,a線程獲取地址里面的值被b線程修改了,那么a線程需要自旋,到下次循環(huán)才有可能機會執(zhí)行。
java.util.concurrent.atomic 包下的類大多是使用CAS操作來實現(xiàn)的( AtomicInteger,AtomicBoolean,AtomicLong)。

16. CAS的問題

1)CAS容易造成ABA問題。一個線程a將數(shù)值改成了b,接著又改成了a,此時CAS認為是沒有變化,其實是已經(jīng)變化過了,而這個問題的解決方案可以使用版本號標識,每操作一次version加1。在java5中,已經(jīng)提供了AtomicStampedReference來解決問題。
2) 不能保證代碼塊的原子性
CAS機制所保證的知識一個變量的原子性操作,而不能保證整個代碼塊的原子性。比如需要保證3個變量共同進行原子性的更新,就不得不使用synchronized了。
3)CAS造成CPU利用率增加。之前說過了CAS里面是一個循環(huán)判斷的過程,如果線程一直沒有獲取到狀態(tài),cpu資源會一直被占用。

17.什么是Future?

在并發(fā)編程中,我們經(jīng)常用到非阻塞的模型,在之前的多線程的三種實現(xiàn)中,不管是繼承thread類還是實現(xiàn)runnable接口,都無法保證獲取到之前的執(zhí)行結(jié)果。通過實現(xiàn)Callback接口,并用Future可以來接收多線程的執(zhí)行結(jié)果。
Future表示一個可能還沒有完成的異步任務的結(jié)果,針對這個結(jié)果可以添加Callback以便在任務執(zhí)行成功或失敗后作出相應的操作。

18.什么是AQS

AQS是AbustactQueuedSynchronizer的簡稱,它是一個Java提高的底層同步工具類,用一個int類型的變量表示同步狀態(tài),并提供了一系列的CAS操作來管理這個同步狀態(tài)。
AQS是一個用來構建鎖和同步器的框架,使用AQS能簡單且高效地構造出應用廣泛的大量的同步器,比如我們提到的ReentrantLock,Semaphore,其他的諸如ReentrantReadWriteLock,SynchronousQueue,F(xiàn)utureTask等等皆是基于AQS的。
AQS支持兩種同步方式:
1.獨占式
2.共享式
這樣方便使用者實現(xiàn)不同類型的同步組件,獨占式如ReentrantLock,共享式如Semaphore,CountDownLatch,組合式的如ReentrantReadWriteLock??傊?,AQS為使用提供了底層支撐,如何組裝實現(xiàn),使用者可以自由發(fā)揮。

19.ReadWriteLock是什么

首先明確一下,不是說ReentrantLock不好,只是ReentrantLock某些時候有局限。如果使用ReentrantLock,可能本身是為了防止線程A在寫數(shù)據(jù)、線程B在讀數(shù)據(jù)造成的數(shù)據(jù)不一致,但這樣,如果線程C在讀數(shù)據(jù)、線程D也在讀數(shù)據(jù),讀數(shù)據(jù)是不會改變數(shù)據(jù)的,沒有必要加鎖,但是還是加鎖了,降低了程序的性能。
因為這個,才誕生了讀寫鎖ReadWriteLock。ReadWriteLock是一個讀寫鎖接口,ReentrantReadWriteLock是ReadWriteLock接口的一個具體實現(xiàn),實現(xiàn)了讀寫的分離,讀鎖是共享的,寫鎖是獨占的,讀和讀之間不會互斥,讀和寫、寫和讀、寫和寫之間才會互斥,提升了讀寫的性能。

20.FutureTask是什么

這個其實前面有提到過,F(xiàn)utureTask表示一個異步運算的任務。FutureTask里面可以傳入一個Callable的具體實現(xiàn)類,可以對這個異步運算的任務的結(jié)果進行等待獲取、判斷是否已經(jīng)完成、取消任務等操作。當然,由于FutureTask也是Runnable接口的實現(xiàn)類,所以FutureTask也可以放入線程池中。

21.synchronized和ReentrantLock的區(qū)別

synchronized是和if、else、for、while一樣的關鍵字,ReentrantLock是類,這是二者的本質(zhì)區(qū)別。既然ReentrantLock是類,那么它就提供了比synchronized更多更靈活的特性,可以被繼承、可以有方法、可以有各種各樣的類變量,ReentrantLock比synchronized的擴展性體現(xiàn)在幾點上:
(1)ReentrantLock可以對獲取鎖的等待時間進行設置,這樣就避免了死鎖
(2)ReentrantLock可以獲取各種鎖的信息
(3)ReentrantLock可以靈活地實現(xiàn)多路通知
另外,二者的鎖機制其實也是不一樣的。ReentrantLock底層調(diào)用的是Unsafe的park方法加鎖,synchronized操作的應該是對象頭中mark word,這點我不能確定。

22.什么是樂觀鎖和悲觀鎖

(1)樂觀鎖:就像它的名字一樣,對于并發(fā)間操作產(chǎn)生的線程安全問題持樂觀狀態(tài),樂觀鎖認為競爭不總是會發(fā)生,因此它不需要持有鎖,將比較-替換這兩個動作作為一個原子操作嘗試去修改內(nèi)存中的變量,如果失敗則表示發(fā)生沖突,那么就應該有相應的重試邏輯。
(2)悲觀鎖:還是像它的名字一樣,對于并發(fā)間操作產(chǎn)生的線程安全問題持悲觀狀態(tài),悲觀鎖認為競爭總是會發(fā)生,因此每次對某資源進行操作時,都會持有一個獨占的鎖,就像synchronized,不管三七二十一,直接上了鎖就操作資源了。

23.線程B怎么知道線程A修改了變量

  • volatile修飾變量
  • synchronized修飾修改變量的方法
  • wait/notify
  • while輪詢

24.synchronized、volatile、CAS比較

  • synchronized是悲觀鎖,屬于搶占式,會引起其他線程阻塞。
  • volatile提供多線程共享變量可見性和禁止指令重排序優(yōu)化。
  • CAS是基于沖突檢測的樂觀鎖(非阻塞)

25.sleep方法和wait方法有什么區(qū)別?

這個問題常問,sleep方法和wait方法都可以用來放棄CPU一定的時間,不同點在于如果線程持有某個對象的監(jiān)視器,sleep方法不會放棄這個對象的監(jiān)視器,wait方法會放棄這個對象的監(jiān)視器

26.ThreadLocal是什么?有什么用?

ThreadLocal是一個本地線程副本變量工具類。主要用于將私有線程和該線程存放的副本對象做一個映射,各個線程之間的變量互不干擾,在高并發(fā)場景下,可以實現(xiàn)無狀態(tài)的調(diào)用,特別適用于各個線程依賴不通的變量值完成操作的場景。
簡單說ThreadLocal就是一種以空間換時間的做法,在每個Thread里面維護了一個以開地址法實現(xiàn)的ThreadLocal.ThreadLocalMap,把數(shù)據(jù)進行隔離,數(shù)據(jù)不共享,自然就沒有線程安全方面的問題了。

27.為什么wait()方法和notify()/notifyAll()方法要在同步塊中被調(diào)用

這是JDK強制的,wait()方法和notify()/notifyAll()方法在調(diào)用前都必須先獲得對象的鎖

28.多線程同步有哪幾種方法?

Synchronized關鍵字,Lock鎖實現(xiàn),分布式鎖等。

29.線程的調(diào)度策略

線程調(diào)度器選擇優(yōu)先級最高的線程運行,但是,如果發(fā)生以下情況,就會終止線程的運行:
(1)線程體中調(diào)用了yield方法讓出了對cpu的占用權利
(2)線程體中調(diào)用了sleep方法使線程進入睡眠狀態(tài)
(3)線程由于IO操作受到阻塞
(4)另外一個更高優(yōu)先級線程出現(xiàn)
(5)在支持時間片的系統(tǒng)中,該線程的時間片用完

30.ConcurrentHashMap的并發(fā)度是什么

ConcurrentHashMap的并發(fā)度就是segment的大小,默認為16,這意味著最多同時可以有16條線程操作ConcurrentHashMap,這也是ConcurrentHashMap對Hashtable的最大優(yōu)勢,任何情況下,Hashtable能同時有兩條線程獲取Hashtable中的數(shù)據(jù)嗎?

31.Java死鎖以及如何避免?

Java中的死鎖是一種編程情況,其中兩個或多個線程被永久阻塞,Java死鎖情況出現(xiàn)至少兩個線程和兩個或更多資源。
Java發(fā)生死鎖的根本原因是:在申請鎖時發(fā)生了交叉閉環(huán)申請。
死鎖的原因
1)是多個線程涉及到多個鎖,這些鎖存在著交叉,所以可能會導致了一個鎖依賴的閉環(huán)。
例如:線程在獲得了鎖A并且沒有釋放的情況下去申請鎖B,這時,另一個線程已經(jīng)獲得了鎖B,在釋放鎖B之前又要先獲得鎖A,因此閉環(huán)發(fā)生,陷入死鎖循環(huán)。
2)默認的鎖申請操作是阻塞的。
所以要避免死鎖,就要在一遇到多個對象鎖交叉的情況,就要仔細審查這幾個對象的類中的所有方法,是否存在著導致鎖依賴的環(huán)路的可能性。 總之是盡量避免在一個同步方法中調(diào)用其它對象的延時方法和同步方法。

32.怎么喚醒一個阻塞的線程

如果線程是因為調(diào)用了wait()、sleep()或者join()方法而導致的阻塞,可以中斷線程,并且通過拋出InterruptedException來喚醒它;如果線程遇到了IO阻塞,無能為力,因為IO是操作系統(tǒng)實現(xiàn)的,Java代碼并沒有辦法直接接觸到操作系統(tǒng)。

33.不可變對象對多線程有什么幫助

前面有提到過的一個問題,不可變對象保證了對象的內(nèi)存可見性,對不可變對象的讀取不需要進行額外的同步手段,提升了代碼執(zhí)行效率。

34.什么是多線程的上下文切換

多線程的上下文切換是指CPU控制權由一個已經(jīng)正在運行的線程切換到另外一個就緒并等待獲取CPU執(zhí)行權的線程的過程。

35.如果你提交任務時,線程池隊列已滿,這時會發(fā)生什么

這里區(qū)分一下:

如果使用的是無界隊列LinkedBlockingQueue,也就是無界隊列的話,沒關系,繼續(xù)添加任務到阻塞隊列中等待執(zhí)行,因為LinkedBlockingQueue可以近乎認為是一個無窮大的隊列,可以無限存放任務
如果使用的是有界隊列比如ArrayBlockingQueue,任務首先會被添加到ArrayBlockingQueue中,ArrayBlockingQueue滿了,會根據(jù)maximumPoolSize的值增加線程數(shù)量,如果增加了線程數(shù)量還是處理不過來,ArrayBlockingQueue繼續(xù)滿,那么則會使用拒絕策略RejectedExecutionHandler處理滿了的任務,默認是AbortPolicy

36.Java中用到的線程調(diào)度算法是什么

搶占式。一個線程用完CPU之后,操作系統(tǒng)會根據(jù)線程優(yōu)先級、線程饑餓情況等數(shù)據(jù)算出一個總的優(yōu)先級并分配下一個時間片給某個線程執(zhí)行。

37.什么是線程調(diào)度器(Thread Scheduler)和時間分片(Time Slicing)?

線程調(diào)度器是一個操作系統(tǒng)服務,它負責為Runnable狀態(tài)的線程分配CPU時間。一旦我們創(chuàng)建一個線程并啟動它,它的執(zhí)行便依賴于線程調(diào)度器的實現(xiàn)。時間分片是指將可用的CPU時間分配給可用的Runnable線程的過程。分配CPU時間可以基于線程優(yōu)先級或者線程等待的時間。線程調(diào)度并不受到Java虛擬機控制,所以由應用程序來控制它是更好的選擇(也就是說不要讓你的程序依賴于線程的優(yōu)先級)。

38.Java Concurrency API中的Lock接口(Lock interface)是什么?對比同步它有什么優(yōu)勢?

Lock接口比同步方法和同步塊提供了更具擴展性的鎖操作。他們允許更靈活的結(jié)構,可以具有完全不同的性質(zhì),并且可以支持多個相關類的條件對象。
它的優(yōu)勢有:

  • 可以使鎖更公平
  • 可以使線程在等待鎖的時候響應中斷
  • 可以讓線程嘗試獲取鎖,并在無法獲取鎖的時候立即返回或者等待一段時間
  • 可以在不同的范圍,以不同的順序獲取和釋放鎖

39.單例模式的線程安全性

老生常談的問題了,首先要說的是單例模式的線程安全意味著:某個類的實例在多線程環(huán)境下只會被創(chuàng)建一次出來。單例模式有很多種的寫法,我總結(jié)一下:
(1)餓漢式單例模式的寫法:線程安全
(2)懶漢式單例模式的寫法:非線程安全
(3)雙檢鎖單例模式的寫法:線程安全

40.Semaphore有什么作用

Semaphore就是一個信號量,它的作用是限制某段代碼塊的并發(fā)數(shù)。Semaphore有一個構造函數(shù),可以傳入一個int型整數(shù)n,表示某段代碼最多只有n個線程可以訪問,如果超出了n,那么請等待,等到某個線程執(zhí)行完畢這段代碼塊,下一個線程再進入。由此可以看出如果Semaphore構造函數(shù)中傳入的int型整數(shù)n=1,相當于變成了一個synchronized了。

41.Executors類是什么?

Executors為Executor,ExecutorService,ScheduledExecutorService,ThreadFactory和Callable類提供了一些工具方法。
Executors可以用于方便的創(chuàng)建線程池

42.線程類的構造方法、靜態(tài)塊是被哪個線程調(diào)用的

這是一個非常刁鉆和狡猾的問題。請記?。壕€程類的構造方法、靜態(tài)塊是被new這個線程類所在的線程所調(diào)用的,而run方法里面的代碼才是被線程自身所調(diào)用的。
如果說上面的說法讓你感到困惑,那么我舉個例子,假設Thread2中new了Thread1,main函數(shù)中new了Thread2,那么:
(1)Thread2的構造方法、靜態(tài)塊是main線程調(diào)用的,Thread2的run()方法是Thread2自己調(diào)用的
(2)Thread1的構造方法、靜態(tài)塊是Thread2調(diào)用的,Thread1的run()方法是Thread1自己調(diào)用的

43.同步方法和同步塊,哪個是更好的選擇

同步塊,這意味著同步塊之外的代碼是異步執(zhí)行的,這比同步整個方法更提升代碼的效率。請知道一條原則:同步的范圍越小越好。

44.Java線程數(shù)過多會造成什么異常?

1)線程的生命周期開銷非常高
2)消耗過多的CPU資源
如果可運行的線程數(shù)量多于可用處理器的數(shù)量,那么有線程將會被閑置。大量空閑的線程會占用許多內(nèi)存,給垃圾回收器帶來壓力,而且大量的線程在競爭CPU資源時還將產(chǎn)生其他性能的開銷。
3)降低穩(wěn)定性
JVM在可創(chuàng)建線程的數(shù)量上存在一個限制,這個限制值將隨著平臺的不同而不同,并且承受著多個因素制約,包括JVM的啟動參數(shù)、Thread構造函數(shù)中請求棧的大小,以及底層操作系統(tǒng)對線程的限制等。如果破壞了這些限制,那么可能拋出OutOfMemoryError異常。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 程序員面試的幾個小技巧

    這篇文章主要介紹了程序員面試的幾個小技巧,在平時面試的時候,除了實打?qū)嵉募寄苓€需要更多的技巧,雙管齊下才能贏得更大的勝算,技能方面就不多說了,下面來分享幾個面試
    2023-04-23
  • AQS底層原理連環(huán)相扣系列鎖面試題分析

    面試中,問鎖主要是兩方面:鎖的日常使用場景 + 鎖原理,鎖的日常使用場景主要考察對鎖 API 的使用熟練度,看看你是否真的使用過這些 API,而不是紙上談兵,鎖原理主要就是
    2022-05-19
  • Mybatis常見面試題詳細總結(jié)

    這篇文章主要介紹了Mybatis常見面試題詳細總結(jié),通過總結(jié)列舉大量的mybatis面試常見題目供給大家參考,希望對大家有所幫助
    2021-08-24
  • 2020Java后端開發(fā)面試題總結(jié)(春招+秋招+社招)

    這篇文章主要介紹了2020Java后端開發(fā)面試題總結(jié)(春招+秋招+社招),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-02-18
  • MySQL數(shù)據(jù)庫選擇題小結(jié)

    這篇文章主要介紹了MySQL數(shù)據(jù)庫選擇題小結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-02-07
  • 30道有趣的JVM面試題(小結(jié))

    這篇文章主要介紹了30道有趣的JVM面試題(小結(jié)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2020-11-26
  • Python面試題爬蟲篇小結(jié)(附答案)

    這篇文章主要介紹了Python面試題爬蟲篇小結(jié)(附答案),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2020-10-28
  • 還不理解B樹和B+樹,那就看看這篇文章吧

    這篇文章主要介紹了還不理解B樹和B+樹,那就看看這篇文章吧,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一
    2020-09-10
  • Java面試通關要點匯總(備戰(zhàn)秋招)

    這篇文章主要介紹了Java面試通關要點匯總(備戰(zhàn)秋招),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2020-09-08
  • 10道JVM常見面試題解析(附答案)

    這篇文章主要介紹了10道JVM常見面試題解析(附答案),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學
    2020-09-04

最新評論