日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

最全多线程经典面试题和答案

發(fā)布時間:2024/7/5 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最全多线程经典面试题和答案 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Java實現(xiàn)線程有哪幾種方式?

1、繼承Thread類實現(xiàn)多線程
2、實現(xiàn)Runnable接口方式實現(xiàn)多線程
3、使用ExecutorService、Callable、Future實現(xiàn)有返回結(jié)果的多線程


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


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

Runnable和Thread用哪個好?

Java不支持類的多重繼承,但允許你實現(xiàn)多個接口。所以如果你要繼承其他類,也為了減少類之間的耦合性,Runnable會更好。


Java中notify和notifyAll有什么區(qū)別?

notify()方法不能喚醒某個具體的線程,所以只有一個線程在等待的時候它才有用武之地。而notifyAll()喚醒所有線程并允許他們爭奪鎖確保了至少有一個線程能繼續(xù)運行。


為什么wait/notify/notifyAll這些方法不在thread類里面?

這是個設計相關的問題,它考察的是面試者對現(xiàn)有系統(tǒng)和一些普遍存在但看起來不合理的事物的看法。回答這些問題的時候,你要說明為什么把這些方法放在Object類里是有意義的,還有不把它放在Thread類里的原因。一個很明顯的原因是JAVA提供的鎖是對象級的而不是線程級的,每個對象都有鎖,通過線程獲得。如果線程需要等待某些鎖那么調(diào)用對象中的wait()方法就有意義了。如果wait()方法定義在Thread類中,線程正在等待的是哪個鎖就不明顯了。簡單的說,由于wait,notify和notifyAll都是鎖級別的操作,所以把他們定義在Object類中因為鎖屬于對象。

為什么wait和notify方法要在同步塊中調(diào)用?

主要是因為Java API強制要求這樣做,如果你不這么做,你的代碼會拋出IllegalMonitorStateException異常。還有一個原因是為了避免wait和notify之間產(chǎn)生競態(tài)條件。

什么是死鎖?如何避免死鎖?

死鎖就是兩個線程相互等待對方釋放對象鎖。

啟動線程方法start()和run()有什么區(qū)別?

只有調(diào)用了start()方法,才會表現(xiàn)出多線程的特性,不同線程的run()方法里面的代碼交替執(zhí)行。如果只是調(diào)用run()方法,那么代碼還是同步執(zhí)行的,必須等待一個線程的run()方法里面的代碼全部執(zhí)行完畢之后,另外一個線程才可以執(zhí)行其run()方法里面的代碼。


多線程之間如何進行通信?

wait/notify

什么是線程池?

很簡單,簡單看名字就知道是裝有線程的池子,我們可以把要執(zhí)行的多線程交給線程池來處理,和連接池的概念一樣,通過維護一定數(shù)量的線程池來達到多個線程的復用。

線程池的好處

我們知道不用線程池的話,每個線程都要通過new Thread(xxRunnable).start()的方式來創(chuàng)建并運行一個線程,線程少的話這不會是問題,而真實環(huán)境可能會開啟多個線程讓系統(tǒng)和程序達到最佳效率,當線程數(shù)達到一定數(shù)量就會耗盡系統(tǒng)的CPU和內(nèi)存資源,也會造成GC頻繁收集和停頓,因為每次創(chuàng)建和銷毀一個線程都是要消耗系統(tǒng)資源的,如果為每個任務都創(chuàng)建線程這無疑是一個很大的性能瓶頸。所以,線程池中的線程復用極大節(jié)省了系統(tǒng)資源,當線程一段時間不再有任務處理時它也會自動銷毀,而不會長駐內(nèi)存。


什么是活鎖、饑餓、無鎖、死鎖?

死鎖、活鎖、饑餓是關于多線程是否活躍出現(xiàn)的運行阻塞障礙問題,如果線程出現(xiàn)了這三種情況,即線程不再活躍,不能再正常地執(zhí)行下去了。

死鎖

死鎖是多線程中最差的一種情況,多個線程相互占用對方的資源的鎖,而又相互等對方釋放鎖,此時若無外力干預,這些線程則一直處理阻塞的假死狀態(tài),形成死鎖。

舉個例子,A同學搶了B同學的鋼筆,B同學搶了A同學的書,兩個人都相互占用對方的東西,都在讓對方先還給自己自己再還,這樣一直爭執(zhí)下去等待對方還而又得不到解決,老師知道此事后就讓他們相互還給對方,這樣在外力的干預下他們才解決,當然這只是個例子沒有老師他們也能很好解決,計算機不像人如果發(fā)現(xiàn)這種情況沒有外力干預還是會一直阻塞下去的。

活鎖

活鎖這個概念大家應該很少有人聽說或理解它的概念,而在多線程中這確實存在。活鎖恰恰與死鎖相反,死鎖是大家都拿不到資源都占用著對方的資源,而活鎖是拿到資源卻又相互釋放不執(zhí)行。當多線程中出現(xiàn)了相互謙讓,都主動將資源釋放給別的線程使用,這樣這個資源在多個線程之間跳動而又得不到執(zhí)行,這就是活鎖。

饑餓

我們知道多線程執(zhí)行中有線程優(yōu)先級這個東西,優(yōu)先級高的線程能夠插隊并優(yōu)先執(zhí)行,這樣如果優(yōu)先級高的線程一直搶占優(yōu)先級低線程的資源,導致低優(yōu)先級線程無法得到執(zhí)行,這就是饑餓。當然還有一種饑餓的情況,一個線程一直占著一個資源不放而導致其他線程得不到執(zhí)行,與死鎖不同的是饑餓在以后一段時間內(nèi)還是能夠得到執(zhí)行的,如那個占用資源的線程結(jié)束了并釋放了資源。

無鎖

無鎖,即沒有對資源進行鎖定,即所有的線程都能訪問并修改同一個資源,但同時只有一個線程能修改成功。無鎖典型的特點就是一個修改操作在一個循環(huán)內(nèi)進行,線程會不斷的嘗試修改共享資源,如果沒有沖突就修改成功并退出否則就會繼續(xù)下一次循環(huán)嘗試。所以,如果有多個線程修改同一個值必定會有一個線程能修改成功,而其他修改失敗的線程會不斷重試直到修改成功。之前的文章我介紹過JDKCAS原理及應用即是無鎖的實現(xiàn)。

可以看出,無鎖是一種非常良好的設計,它不會出現(xiàn)線程出現(xiàn)的跳躍性問題,鎖使用不當肯定會出現(xiàn)系統(tǒng)性能問題,雖然無鎖無法全面代替有鎖,但無鎖在某些場合下是非常高效的。

Synchronized有哪幾種用法?

鎖類、鎖方法、鎖代碼塊。

Fork/Join框架是干什么的?

大任務自動分散小任務,并發(fā)執(zhí)行,合并小任務結(jié)果。

Java中用到了什么線程調(diào)度算法?

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


你可能也喜歡:

  • Java多線程系列(二):線程的五大狀態(tài),以及線程之間的通信與協(xié)作
  • Java多線程系列(七):并發(fā)容器的原理,7大并發(fā)容器詳解、及使用場景
  • Java多線程系列(八):ConcurrentHashMap的實現(xiàn)原理(JDK1.7和JDK1.8)
  • 史上最強多線程面試44題和答案:線程鎖+線程池+線程同步等
  • Java多線程系列(一):最全面的Java多線程學習概述
  • Java多線程系列(五):線程池的實現(xiàn)原理、優(yōu)點與風險、以及四種線程池實現(xiàn)

  • 總結(jié)

    以上是生活随笔為你收集整理的最全多线程经典面试题和答案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。