多線程技術在互聯(lián)網技術方面使用如此廣泛,幾乎所有的后端技術面試官都要在并發(fā)編程的使用和原理方面對小伙伴們進行各種刁難。作為一名在互聯(lián)網技術行業(yè)打擊過成百上千名【請允許我夸張一下】的資深技術面試官,看過了無數(shù)落寞的身影失望的離開,略感愧疚,故獻上此文,希望各位讀者以后面試勢如破竹,永無失敗!
覺得文章對你有幫助的話,可以點贊關注一下,給作者一點小鼓勵。
什么是線程?
線程是操作系統(tǒng)能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位,可以使用多線程對進行運算提速。
比如,如果一個線程完成一個任務要100毫秒,那么用十個線程完成改任務只需10毫秒
什么是多線程?優(yōu)缺點?
什么是多線程?
多線程:是指從軟件或者硬件上實現(xiàn)多個線程的并發(fā)技術。
多線程的好處:
使用多線程可以把程序中占據(jù)時間長的任務放到后臺去處理,如圖片、視屏的下載
發(fā)揮多核處理器的優(yōu)勢,并發(fā)執(zhí)行讓系統(tǒng)運行的更快、更流暢,用戶體驗更好
多線程的缺點:
大量的線程降低代碼的可讀性;
更多的線程需要更多的內存空間
當多個線程對同一個資源出現(xiàn)爭奪時候要注意線程安全的問題。
線程的五個狀態(tài)(五種狀態(tài),創(chuàng)建、就緒、運行、阻塞和死亡)?
線程通常都有五種狀態(tài),創(chuàng)建、就緒、運行、阻塞和死亡。
第一是創(chuàng)建狀態(tài)。在生成線程對象,并沒有調用該對象的start方法,這是線程處于創(chuàng)建狀態(tài)。
第二是就緒狀態(tài)。當調用了線程對象的start方法之后,該線程就進入了就緒狀態(tài),但是此時線程調度程序還沒有把該線程設置為當前線程,此時處于就緒狀態(tài)。在線程運行之后,從等待或者睡眠中回來之后,也會處于就緒狀態(tài)。
第三是運行狀態(tài)。線程調度程序將處于就緒狀態(tài)的線程設置為當前線程,此時線程就進入了運行狀態(tài),開始運行run函數(shù)當中的代碼。
第四是阻塞狀態(tài)。線程正在運行的時候,被暫停,通常是為了等待某個時間的發(fā)生(比如說某項資源就緒)之后再繼續(xù)運行。sleep,suspend,wait等方法都可以導致線程阻塞。
第五是死亡狀態(tài)。如果一個線程的run方法執(zhí)行結束或者調用stop方法后,該線程就會死亡。對于已經死亡的線程,無法再使用start方法令其進入就緒
什么是CAS?
CAS(compare and swap)的縮寫,中文翻譯成比較并交換。
CAS 不通過JVM,直接利用java本地方 JNI(Java Native Interface為JAVA本地調用),直接調用CPU 的cmpxchg(是匯編指令)指令。
利用CPU的CAS指令,同時借助JNI來完成Java的非阻塞算法,實現(xiàn)原子操作。其它原子操作都是利用類似的特性完成的。
整個java.util.concurrent都是建立在CAS之上的,因此對于synchronized阻塞算法,J.U.C在性能上有了很大的提升。
CAS是項樂觀鎖技術,當多個線程嘗試使用CAS同時更新同一個變量時,只有其中一個線程能更新變量的值,而其它線程都失敗,失敗的線程并不會被掛起,而是被告知這次競爭中失敗,并可以再次嘗試。
CAS應用
CAS有3個操作數(shù),內存值V,舊的預期值A,要修改的新值B。當且僅當預期值A和內存值V相同時,將內存值V修改為B,否則什么都不做。
CAS優(yōu)點
確保對內存的讀-改-寫操作都是原子操作執(zhí)行
CAS缺點
CAS雖然很高效的解決原子操作,但是CAS仍然存在三大問題。ABA問題,循環(huán)時間長開銷大和只能保證一個共享變量的原子操作
什么是AQS?
AbstractQueuedSynchronizer簡稱AQS,是一個用于構建鎖和同步容器的框架。事實上concurrent包內許多類都是基于AQS構建,例如ReentrantLock,Semaphore,CountDownLatch,ReentrantReadWriteLock,F(xiàn)utureTask等。AQS解決了在實現(xiàn)同步容器時設計的大量細節(jié)問題。
AQS使用一個FIFO的隊列表示排隊等待鎖的線程,隊列頭節(jié)點稱作“哨兵節(jié)點”或者“啞節(jié)點”,它不與任何線程關聯(lián)。其他的節(jié)點與等待線程關聯(lián),每個節(jié)點維護一個等待狀態(tài)waitStatus。
什么是樂觀鎖和悲觀鎖?
悲觀鎖
Java在JDK1.5之前都是靠synchronized關鍵字保證同步的,這種通過使用一致的鎖定協(xié)議來協(xié)調對共享狀態(tài)的訪問,可以確保無論哪個線程持有共享變量的鎖,都采用獨占的方式來訪問這些變量。獨占鎖其實就是一種悲觀鎖,所以可以說synchronized是悲觀鎖。
樂觀鎖
樂觀鎖( Optimistic Locking)其實是一種思想。相對悲觀鎖而言,樂觀鎖假設認為數(shù)據(jù)一般情況下不會造成沖突,所以在數(shù)據(jù)進行提交更新的時候,才會正式對數(shù)據(jù)的沖突與否進行檢測,如果發(fā)現(xiàn)沖突了,則讓返回用戶錯誤的信息,讓用戶決定如何去做。
并發(fā)編程(concurrency)并行編程(parallellism)有什么區(qū)別?
并發(fā)(concurrency)和并行(parallellism)是:
解釋一:并行是指兩個或者多個事件在同一時刻發(fā)生;而并發(fā)是指兩個或多個事件在同一時間間隔發(fā)生。
解釋二:并行是在不同實體上的多個事件,并發(fā)是在同一實體上的多個事件。
解釋三:在一臺處理器上“同時”處理多個任務,在多臺處理器上同時處理多個任務。如hadoop分布式集群
所以并發(fā)編程的目標是充分的利用處理器的每一個核,以達到最高的處理性能。
想要了解更多多線程知識點的,可以加群650385180,多線程的學習資料以及多線程面試題匯總都在群的共享區(qū)供大家免費下載。
怎么喚醒一個阻塞的線程?
如果線程是因為調用了wait()、sleep()或者join()方法而導致的阻塞,可以中斷線程,并且通過拋出InterruptedException來喚醒它;如果線程遇到了IO阻塞,無能為力,因為IO是操作系統(tǒng)實現(xiàn)的,Java代碼并沒有辦法直接接觸到操作系統(tǒng)。
如何檢測死鎖?怎么預防死鎖?
所謂死鎖:是指兩個或兩個以上的進程在執(zhí)行過程中,因爭奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進下去。此時稱系統(tǒng)處于死鎖
通俗地講就是兩個或多個進程被無限期地阻塞、相互等待的一種狀態(tài)
死鎖產生的原因?
1.因競爭資源發(fā)生死鎖 現(xiàn)象:系統(tǒng)中供多個進程共享的資源的數(shù)目不足以滿足全部進程的需要時,就會引起對諸資源的競爭而發(fā)生死鎖現(xiàn)象
2.進程推進順序不當發(fā)生死鎖
死鎖的四個必要條件:
互斥條件:進程對所分配到的資源不允許其他進程進行訪問,若其他進程訪問該資源,只能等待,直至占有該資源的進程使用完成后釋放該資源
請求和保持條件:進程獲得一定的資源之后,又對其他資源發(fā)出請求,但是該資源可能被其他進程占有,此事請求阻塞,但又對自己獲得的資源保持不放
不可剝奪條件:是指進程已獲得的資源,在未完成使用之前,不可被剝奪,只能在使用完后自己釋放
環(huán)路等待條件:是指進程發(fā)生死鎖后,若干進程之間形成一種頭尾相接的循環(huán)等待資源關系
這四個條件是死鎖的必要條件,只要系統(tǒng)發(fā)生死鎖,這些條件必然成立,而只要上述條件之
一不滿足,就不會發(fā)生死鎖。
檢測死鎖
有兩個容器,一個用于保存線程正在請求的鎖,一個用于保存線程已經持有的鎖。每次加鎖之前都會做如下檢測:
檢測當前正在請求的鎖是否已經被其它線程持有,如果有,則把那些線程找出來
遍歷第一步中返回的線程,檢查自己持有的鎖是否正被其中任何一個線程請求,如果第二步返回真,表示出現(xiàn)了死鎖
死鎖的解除與預防:
理解了死鎖的原因,尤其是產生死鎖的四個必要條件,就可以最大可能地避免、預防和解除死鎖。
所以,在系統(tǒng)設計、進程調度等方面注意如何不讓這四個必要條件成立,如何確定資源的合理分配算法,避免進程永久占據(jù)系統(tǒng)資源。
此外,也要防止進程在處于等待狀態(tài)的情況下占用資源。因此,對資源的分配要給予合理的規(guī)劃。
想要了解更多多線程知識點的,可以加群650385180,多線程的學習資料以及多線程面試題匯總都在群的共享區(qū)供大家免費下載。
更多多線程面試題
什么是原子操作?在Java Concurrency API中有哪些原子類(atomic classes)?
什么是Executors框架?
什么是阻塞隊列?如何使用阻塞隊列來實現(xiàn)生產者-消費者模型?
什么是Callable和Future?
什么是FutureTask?
什么是同步容器和并發(fā)容器的實現(xiàn)?
什么是多線程的上下文切換?
ThreadLocal的設計理念與作用?
ThreadPool(線程池)用法與優(yōu)勢?
加群:650385180獲取更多多線程知識點及面試題
Concurrent包里的其他東西:ArrayBlockingQueue、CountDownLatch等等。
synchronized和ReentrantLock的區(qū)別?
Semaphore有什么作用?
Java Concurrency API中的Lock接口(Lock interface)是什么?對比同步它有什么優(yōu)勢?
總結
關于Java多線程面試技術點的一些總結已經寫完了,受限于我的視野,所以可能寫的不是很全面,大家要是有不同意見的,可以分享出來,一起交流,要是想深入了解多線程技術知識點的,可以加上面的群,希望可以幫助在這個行業(yè)發(fā)展的朋友和童鞋們,在論壇博客等地方少花些時間找資料,把有限的時間,真正花在學習上。
評論
查看更多