多線程面試59題(含答案)_第1頁
多線程面試59題(含答案)_第2頁
多線程面試59題(含答案)_第3頁
多線程面試59題(含答案)_第4頁
多線程面試59題(含答案)_第5頁
已閱讀5頁,還剩5頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

發(fā)揮多核CPU,4核、816CPU上50%4CPU75%CPU上所謂的"多線程"那是看著像多個線程"同時"運行罷了。多核CPU上的多線程才是真正的多線程,它能讓你的多段邏輯同時工作,多線程,可以真正發(fā)揮出多核CPU的優(yōu)勢來,達到充分利用CPU的目的。CPU不但不會發(fā)揮出多線程的優(yōu)勢,反而會因為在單核CPU上運行多線程導致線程上下文的切換,而降低程序整體的效率。但就要考慮很多,建立整個程序模型比較麻煩。但是如果把這個大的任務A分解成幾個小任務,任務BCD,分別建立程序模型,并通過多線程分別運JavaThreadRunnableExecutorService、Callable、Futurestartrun碼交替執(zhí)行。如果只是調(diào)用run()方法,那么代碼還是同步執(zhí)行的,必須等待一個run()run()stopRUNNABLE:start()方式調(diào)用,線程正式啟動,線程處于運行中BLOCKED:表示線程阻塞,等待獲取鎖,如碰到synchronized、lockRBE狀態(tài)繼續(xù)運行。WNG:表示線程處于無限制等待狀態(tài),等待一個特殊的事件來重新喚醒,如通過it()noti()notiAll()join()方法進行等待的線程等待目標線程運行結(jié)束而喚醒,一旦通過相關(guān)事件喚醒線程,線RBE狀態(tài)繼續(xù)運行。TIMED_WAITINGsleep(3000)3秒RUNNABLE狀態(tài)繼續(xù)運行。通過startNEW狀態(tài),線程終止后也不能再回到RUNNABLE狀態(tài)waitsleep(于如果線程持有某個對象的監(jiān)視器,sleep方法不會放棄這個對象的監(jiān)視器,waitSynchronized關(guān)鍵字,Lock實現(xiàn)Callable一個非常重要的問題,是每個學習、應用多線程的Java程序員都必須掌握的。理了,可以參見第31點,volatile關(guān)鍵字的作用主要有兩個:volatile變量,一定是最新的代碼底層執(zhí)行不像我們看到的高級語言Java代碼-->字節(jié)碼-->根據(jù)字節(jié)碼執(zhí)行對應的C/C++代碼-->C/C++代碼被編譯成匯編語言-->JVM可能會對指令進行重排volatile則會對禁止語義重排序,當然這也一定程度上降低了代碼執(zhí)行效率從實踐角度而言,volatile的一個重CASjava.util.concurrent.atomicAtomicInteger。、新建join143我們知道不用線程池的話,每個線程都要通過newThread(xxRunnable).start()的方CPU和GC頻繁收集和停頓,因為每次創(chuàng)建和銷毀一個線程都是要消我們知道不用線程池的話,每個線程都要通過newThread(xxRunnable).start()的方線程讓系統(tǒng)和程序達到最佳效率,當線程數(shù)達到一定數(shù)量就會耗盡系統(tǒng)的CPU和內(nèi)存資源,也會造成GC頻繁收集和停頓,因為每次創(chuàng)建和銷毀一個線程都是要消java.util.concurrent包中我們能找到線程池的定義,其中ThreadPoolExecutor是ExecutorServicees=submitexecuteexecuteexecute方法,性能會好很submitFuturesubmit提交,而且它能Futureget方法捕獲線程中的異常。如何關(guān)閉線程池list()和executeexecute方法,性能會好很submitFuturesubmit提交,而且它能Futureget方法捕獲線程中的異常。18、CyclicBarrierCountDownLatch兩個看上去有點像的類,都在java.util.concurrent下,都可以用來表示代碼運行到CyclicBarrier的某個線程運行到某個點上之后,該線程即停止運行,直到所有的線程都到達了這個點,所有線程才重新運行;CountDownLatch則不是,某線程運行到某個點上之后,只是給某個數(shù)值-1而已,該線程繼續(xù)運行CyclicBarrier只能喚起一個任務,CountDownLatch可以喚起多個任務3.CyclicBarrierCountDownLatch0該死鎖是多線程中最差的一種情況,多個線程相互占用對方的資源的鎖,而又相互等舉個例子,AB同學的鋼筆,BA同學的書,兩個人都相互占用對方的東西,都在讓對方先還給自己自己再還,這樣一直爭執(zhí)下去等待對方還而又得不到解決,老師知道此事后就讓他們相互還給對方,這樣在外力的干預下他們才解決,當然這只是個例子沒有老師他們也能很好解決,計算機不像人如果發(fā)現(xiàn)這種情況沒有外力干預還是會一直阻塞下去的。無鎖,即沒有對資源進行鎖定,即所有的線程都能訪問并修改同一個資源,但同時只有一個線程能修改成功。無鎖典型的特點就是一個修改操作在一個循環(huán)內(nèi)進行,線程會不斷的嘗試修改共享資源,如果沒有沖突就修改成功并退出否則就會繼續(xù)下而其他修改失敗的線程會不斷重試直到修改成功。之前的文章我介紹過JK的CS原理及應用即是無鎖的實現(xiàn)。n++100n0,n最后的100n++并不AtomicInteger保證原子性。其他線程是不可見的,所以其他線程從主內(nèi)存讀到的值是修改之前的舊值。像CPUJVM編譯器的優(yōu)化,都會出現(xiàn)可見性我們都知道程序是按代碼順序執(zhí)行的,對于單線程來說確實是如此,但在多線程情CPU的處理性能,JM和操作系統(tǒng)都會對指令進行重排,也就說前面的代碼并不一定都會在后面的代碼前面執(zhí)行,即后面的代碼可能會插到前面的代碼之前執(zhí)行,只要不影響當前線程的執(zhí)行結(jié)果。所以,指令重排只會保證當前線程執(zhí)行結(jié)果一致,但指令重排后勢必會影響多線程的執(zhí)如果異常沒有被捕獲該線程將會停止執(zhí)行。Thread.UncaughtExceptionHandler是用JVMThread.getUncaughtExceptionHandler()UncaughtExceptionHandlerhandler的、線程Yield方法可以暫停當前正在執(zhí)行的線程對象,讓其它有相同優(yōu)先級的線程執(zhí)行。CPU占用而不能保證使其它線程一定CPU,執(zhí)行yield()的線程有可能在進入到暫停狀態(tài)后馬上又被執(zhí)行。JavaMapHashMap了,它是線程不安全的。HashMapHashMap操作這時候就存在線程安全的問題了。29CASCASCompareandSwap,即比較-V、ABAV相同時,才會將內(nèi)AACAS操作失敗,永遠java.util.concurrent.atomicAtom****CASjava.lang.Thread#holdsLock123、線程await/signal/signalAllBlockingQueue就是為線程synchronized37LockThreadLocal的作用是提供線程內(nèi)的局部變量,這種變量在線程的生命周期內(nèi)起作解決數(shù)據(jù)庫連接、Session管理等。ReadWriteLock是一個讀寫鎖接口,ReentrantReadWriteLockReadWriteLock接40、FutureTaskFutureTask表示一個異步運算的任務,F(xiàn)utureTaskCallableInterruptedExceptionIO阻塞,無能為力,IO是操作系統(tǒng)實現(xiàn)的,Java代碼并沒有辦法直接接觸到操作系統(tǒng)。CPU控制權(quán)由一個已經(jīng)正在運行的線程切換到另外一個CPU執(zhí)行權(quán)的線程的過程。CPU之后,操作系統(tǒng)會根據(jù)線程優(yōu)先級、線程饑餓情況等JavaCPUCPU控制權(quán),可以使46、JavaJVM程序計數(shù)器(ProgramCounter虛擬機棧(VM虛擬機棧描述的是Java方法執(zhí)行的內(nèi)存模型,每個方法被執(zhí)行的時候都會同時創(chuàng)建一個棧幀(StackFrame)用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口本地方法棧(NativeMethod本地方法棧用于支持本地方法(nativeJava語言實現(xiàn)的方法)。JVM允許的最大容量時拋出StackOverflowError異常。JVM啟動時創(chuàng)建的數(shù)組和對象,JVM垃圾收集也如果實際所需的堆超過了自動內(nèi)存管理系統(tǒng)能提供的最大容量時拋出OutOfMemoryError異常。方法區(qū)(MethodArea)運行時常量池(RuntimeConstantPool)、字段和方法數(shù)據(jù)、構(gòu)造函數(shù)和普通方法OutOfMemoryError運行時常量池(RuntimeConstantJM的方法區(qū)中,JM后,對應的運行時常量池就被創(chuàng)建。運行時常量池是每一個類或接口的常量池(Constnt_Poo)編譯器可知的數(shù)值字面量到必須運行期解析后才能獲得的方法或字段的引用。如果方法區(qū)的內(nèi)存空間不能滿足內(nèi)存分配請求,那JvautMmoErorams,當調(diào)用方法時,ame被推送到堆棧。ame包含局部變量數(shù)組、操作數(shù)棧、常量池引用。觀鎖認為競爭不總是會發(fā)生,因此它不需要持有鎖,將比較-替換這兩個動作作為相應的重試邏輯。48、HashtablesizeAHashtableputBsize()Hashtable中當前元素的個數(shù),那讀取到的值可能不是最新的,可能線程A添加了完了數(shù)據(jù),但是沒有對size()Bsize()Aput方法完畢之后才可以調(diào)用,這樣就保證了線程安全性CPU執(zhí)行代碼,執(zhí)行Java代碼,這點很關(guān)鍵,一定得記住。Java代碼最終是被翻譯成機器碼執(zhí)行的,機器碼才是真正可以和硬件電路交互的代碼。即使你看到Java代碼只有一行,甚至你看到Java代碼編譯之后生成的字節(jié)碼也只有一行,也不意味著對于底層來說這句語句的操作只有一個。一句"returncount"假設(shè)被翻譯成了三句匯編語句51、RunnableThreadJava為了減少類之間的耦合性,Runnable52、JavanotifynotifyAllnoti()方法不能喚醒某個具體的線程,所以只有一個線程在等待的時候它才有用武之地。notifyAll()喚醒所有線程并允許他們爭奪鎖確保了至少有一個線程能繼續(xù)運行。53、為什么wait/notify/notifyAll這些方法不在thread類里面?Object類里是有意義的,還有不把它放在Thread類里的原因。一個很明顯的原因是JAVA提供的鎖是對象級的而不是線程級的,每個對象都有鎖,通過線程獲得。如果線程需要等待某些鎖那么調(diào)用對象中的wait()wait()方法定Threadwait,notifynotifyAllObject類中因為鎖屬于對54waitnotifyJavaAPIIllegalMonitorStateExceptionwaitnotify程序就會在沒有滿足結(jié)束條件的情況下退出。因此,當一個等待線程醒來時,不能認為它原來的等待狀態(tài)仍然是有效的,在noti()方法調(diào)用之后和等待線程醒來之it()方法效果更好的原因,你可以lipseitnotiy試一試。volatile變量就可以發(fā)揮作用了,它要求線程57Java對于不同的操作系統(tǒng),有多種方法來獲得Java進程的線程堆棧。當你獲取線程堆棧時,J

溫馨提示

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

評論

0/150

提交評論