程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java多線程和並發基本面試題(問答情勢)

Java多線程和並發基本面試題(問答情勢)

編輯:關於JAVA

Java多線程和並發基本面試題(問答情勢)。本站提示廣大學習愛好者:(Java多線程和並發基本面試題(問答情勢))文章只能為提供參考,不一定能成為您想要的結果。以下是Java多線程和並發基本面試題(問答情勢)正文


本文贊助年夜家控制Java多線程基本常識來對應往後碰著的成績,詳細內容以下

1、Java多線程面試成績

1. 過程和線程之間有甚麼分歧?
一個過程是一個自力(self contained)的運轉情況,它可以被看做一個法式或許一個運用。而線程是在過程中履行的一個義務。Java運轉情況是一個包括了分歧的類和法式的單一過程。線程可以被稱為輕量級過程。線程須要較少的資本來創立和駐留在過程中,而且可以同享過程中的資本。

2. 多線程編程的利益是甚麼?
在多線程法式中,多個線程被並發的履行以進步法式的效力,CPU不會由於某個線程須要期待資本而進入余暇狀況。多個線程同享堆內存(heap memory),是以創立多個線程去履行一些義務會比創立多個過程更好。舉個例子,Servlets比CGI更好,是由於Servlets支撐多線程而CGI不支撐。

3. 用戶線程和守護線程有甚麼差別?
當我們在Java法式中創立一個線程,它就被稱為用戶線程。一個守護線程是在後台履行而且不會阻攔JVM終止的線程。當沒有效戶線程在運轉的時刻,JVM封閉法式而且加入。一個守護線程創立的子線程仍然是守護線程。

4. 我們若何創立一個線程?
有兩種創立線程的辦法:一是完成Runnable接口,然後將它傳遞給Thread的結構函數,創立一個Thread對象;二是直接繼續Thread類。若想懂得更多可以浏覽這篇關於若何在Java中創立線程的文章。

5. 有哪些分歧的線程性命周期?
當我們在Java法式中新建一個線程時,它的狀況是New。當我們挪用線程的start()辦法時,狀況被轉變為Runnable。線程調劑器會為Runnable線程池中的線程分派CPU時光而且講它們的狀況轉變為Running。其他的線程狀況還有Waiting,Blocked 和Dead。讀這篇文章可以懂得更多關於線程性命周期的常識。

6. 可以直接挪用Thread類的run()辦法麼?
固然可以,然則假如我們挪用了Thread的run()辦法,它的行動就會和通俗的辦法一樣,為了在新的線程中履行我們的代碼,必需應用Thread.start()辦法。

7. 若何讓正在運轉的線程暫停一段時光?
我們可使用Thread類的Sleep()辦法讓線程暫停一段時光。須要留意的是,這其實不會讓線程終止,一旦從休眠中叫醒線程,線程的狀況將會被轉變為Runnable,而且依據線程調劑,它將獲得履行。

8. 你對線程優先級的懂得是甚麼?
每個線程都是有優先級的,普通來講,高優先級的線程在運轉時會具有優先權,但這依附於線程調劑的完成,這個完成是和操作體系相干的(OS dependent)。我們可以界說線程的優先級,然則這其實不能包管高優先級的線程會在低優先級的線程前履行。線程優先級是一個int變量(從1-10),1代表最低優先級,10代表最高優先級。

9. 甚麼是線程調劑器(Thread Scheduler)和時光分片(Time Slicing)?
線程調劑器是一個操作體系辦事,它擔任為Runnable狀況的線程分派CPU時光。一旦我們創立一個線程並啟動它,它的履行便依附於線程調劑器的完成。時光分片是指將可用的CPU時光分派給可用的Runnable線程的進程。分派CPU時光可以基於線程優先級或許線程期待的時光。線程調劑其實不遭到Java虛擬機掌握,所以由運用法式來掌握它是更好的選擇(也就是說不要讓你的法式依附於線程的優先級)。

10. 在多線程中,甚麼是高低文切換(context-switching)?
高低文切換是存儲和恢復CPU狀況的進程,它使得線程履行可以或許從中止點恢復履行。高低文切換是多義務操作體系和多線程情況的根本特點。

11. 你若何確保main()辦法地點的線程是Java法式最初停止的線程?
我們可使用Thread類的joint()辦法來確保一切法式創立的線程在main()辦法加入前停止。這裡有一篇文章關於Thread類的joint()辦法。

12.線程之間是若何通訊的?
當線程間是可以同享資本時,線程間通訊是調和它們的主要的手腕。Object類中wait()\notify()\notifyAll()辦法可以用於線程間通訊關於資本的鎖的狀況。點擊這裡有更多關於線程wait, notify和notifyAll.

13.為何線程通訊的辦法wait(), notify()和notifyAll()被界說在Object類裡?
Java的每一個對象中都有一個鎖(monitor,也能夠成為監督器) 而且wait(),notify()等辦法用於期待對象的鎖或許告訴其他線程對象的監督器可用。在Java的線程中並沒有可供任何對象應用的鎖和同步器。這就是為何這些辦法是Object類的一部門,如許Java的每個類都有效於線程間通訊的根本辦法

14. 為何wait(), notify()和notifyAll()必需在同步辦法或許同步塊中被挪用?
當一個線程須要挪用對象的wait()辦法的時刻,這個線程必需具有該對象的鎖,接著它就會釋放這個對象鎖並進入期待狀況直到其他線程挪用這個對象上的notify()辦法。異樣的,當一個線程須要挪用對象的notify()辦法時,它會釋放這個對象的鎖,以便其他在期待的線程便可以獲得這個對象鎖。因為一切的這些辦法都須要線程持有對象的鎖,如許就只能經由過程同步來完成,所以他們只能在同步辦法或許同步塊中被挪用。

15. 為何Thread類的sleep()和yield()辦法是靜態的?
Thread類的sleep()和yield()辦法將在以後正在履行的線程上運轉。所以在其他處於期待狀況的線程上挪用這些辦法是沒成心義的。這就是為何這些辦法是靜態的。它們可以在以後正在履行的線程中任務,並防止法式員毛病的以為可以在其他非運轉線程挪用這些辦法。

16.若何確保線程平安?
在Java中可以有許多辦法來包管線程平安——同步,應用原子類(atomic concurrent classes),完成並發鎖,應用volatile症結字,應用不變類和線程平安類。在線程平安教程中,你可以學到更多。

17. volatile症結字在Java中有甚麼感化?
當我們應用volatile症結字去潤飾變量的時刻,所以線程都邑直接讀取該變量而且不緩存它。這就確保了線程讀取到的變量是同內存中是分歧的。

18. 同步辦法和同步塊,哪一個是更好的選擇?
同步塊是更好的選擇,由於它不會鎖住全部對象(固然你也能夠讓它鎖住全部對象)。同步辦法會鎖住全部對象,哪怕這個類中有多個不相干聯的同步塊,這平日會招致他們停滯履行並須要期待取得這個對象上的鎖。

19.若何創立守護線程?
應用Thread類的setDaemon(true)辦法可以將線程設置為守護線程,須要留意的是,須要在挪用start()辦法前挪用這個辦法,不然會拋出IllegalThreadStateException異常。

20. 甚麼是ThreadLocal?
ThreadLocal用於創立線程的當地變量,我們曉得一個對象的一切線程會同享它的全局變量,所以這些變量不是線程平安的,我們可使用同步技巧。然則當我們不想應用同步的時刻,我們可以選擇ThreadLocal變量。

每一個線程都邑具有他們本身的Thread變量,它們可使用get()\set()辦法去獲得他們的默許值或許在線程外部轉變他們的值。ThreadLocal實例平日是願望它們同線程狀況聯系關系起來是private static屬性。在ThreadLocal例子這篇文章中你可以看到一個關於ThreadLocal的小法式。

21. 甚麼是Thread Group?為何不建議應用它?
ThreadGroup是一個類,它的目標是供給關於線程組的信息。

ThreadGroup API比擬軟弱,它並沒有比Thread供給了更多的功效。它有兩個重要的功效:一是獲得線程組中處於活潑狀況線程的列表;二是設置為線程設置未捕捉異常處置器(ncaught exception handler)。但在Java 1.5中Thread類也添加了setUncaughtExceptionHandler(UncaughtExceptionHandler eh) 辦法,所以ThreadGroup是曾經過時的,不建議持續應用。

t1.setUncaughtExceptionHandler(new UncaughtExceptionHandler(){

 @Override
 public void uncaughtException(Thread t, Throwable e) {
 System.out.println("exception occured:"+e.getMessage());
 }
});

22. 甚麼是Java線程轉儲(Thread Dump),若何獲得它?
線程轉儲是一個JVM運動線程的列表,它關於剖析體系瓶頸和逝世鎖異常有效。有許多辦法可以獲得線程轉儲——應用Profiler,Kill -3敕令,jstack對象等等。我更愛好jstack對象,由於它輕易應用而且是JDK自帶的。因為它是一個基於終真個對象,所以我們可以編寫一些劇本去准時的發生線程轉儲以待剖析。讀這篇文檔可以懂得更多關於發生線程轉儲的常識。

23. 甚麼是逝世鎖(Deadlock)?若何剖析和防止逝世鎖?
逝世鎖是指兩個以上的線程永久壅塞的情形,這類情形發生至多須要兩個以上的線程和兩個以上的資本。

剖析逝世鎖,我們須要檢查Java運用法式的線程轉儲。我們須要找出那些狀況為BLOCKED的線程和他們期待的資本。每一個資本都有一個獨一的id,用這個id我們可以找出哪些線程曾經具有了它的對象鎖。

防止嵌套鎖,只在須要的處所應用鎖和防止無窮期期待是防止逝世鎖的平日方法,浏覽這篇文章去進修若何剖析逝世鎖。

24. 甚麼是Java Timer類?若何創立一個有特准時間距離的義務?
java.util.Timer是一個對象類,可以用於支配一個線程在將來的某個特准時間履行。Timer類可以用支配一次性義務或許周期義務。

java.util.TimerTask是一個完成了Runnable接口的籠統類,我們須要去繼續這個類來創立我們本身的准時義務並應用Timer去支配它的履行。

25. 甚麼是線程池?若何創立一個Java線程池?
一個線程池治理了一組任務線程,同時它還包含了一個用於放置期待履行的義務的隊列。

java.util.concurrent.Executors供給了一個 java.util.concurrent.Executor接口的完成用於創立線程池。線程池例子展示了若何創立和應用線程池,或許浏覽ScheduledThreadPoolExecutor例子,懂得若何創立一個周期義務。

2、Java並發面試成績

1. 甚麼是原子操作?在Java Concurrency API中有哪些原子類(atomic classes)?
原子操作是指一個不受其他操作影響的操作義務單位。原子操作是在多線程情況下防止數據紛歧致必需的手腕。

int++其實不是一個原子操作,所以當一個線程讀取它的值並加1時,別的一個線程有能夠會讀到之前的值,這就會激發毛病。

為懂得決這個成績,必需包管增長操作是原子的,在JDK1.5之前我們可使用同步技巧來做到這一點。到JDK1.5,java.util.concurrent.atomic包供給了int和long類型的裝類,它們可以主動的包管關於他們的操作是原子的而且不須要應用同步。

2. Java Concurrency API中的Lock接口(Lock interface)是甚麼?比較同步它有甚麼優勢?
Lock接口比同步辦法和同步塊供給了更具擴大性的鎖操作。他們許可更靈巧的構造,可以具有完整分歧的性質,而且可以支撐多個相干類的前提對象。

它的優勢有:

可使鎖更公正
可使線程在期待鎖的時刻呼應中止
可讓線程測驗考試獲得鎖,並在沒法獲得鎖的時刻立刻前往或許期待一段時光
可以在分歧的規模,以分歧的次序獲得和釋放鎖

3. 甚麼是Executors框架?
Executor框架同java.util.concurrent.Executor 接口在Java 5中被引入。Executor框架是一個依據一組履行戰略挪用,調劑,履行和掌握的異步義務的框架。

無窮制的創立線程會惹起運用法式內存溢出。所以創立一個線程池是個更好的的處理計劃,由於可以限制線程的數目而且可以收受接管再應用這些線程。應用Executors框架可以異常便利的創立一個線程池,浏覽這篇文章可以懂得若何應用Executor框架創立一個線程池。

4. 甚麼是壅塞隊列?若何應用壅塞隊列來完成臨盆者-花費者模子?
java.util.concurrent.BlockingQueue的特征是:當隊列是空的時,從隊列中獲得或刪除元素的操作將會被壅塞,或許當隊列是滿時,往隊列裡添加元素的操作會被壅塞。

壅塞隊列不接收空值,當你測驗考試向隊列中添加空值的時刻,它會拋出NullPointerException。

壅塞隊列的完成都是線程平安的,一切的查詢辦法都是原子的而且應用了外部鎖或許其他情勢的並發掌握。

BlockingQueue 接口是java collections框架的一部門,它重要用於完成臨盆者-花費者成績。

5. 甚麼是Callable和Future?
Java 5在concurrency包中引入了java.util.concurrent.Callable 接口,它和Runnable接口很類似,但它可以前往一個對象或許拋出一個異常。

Callable接口應用泛型去界說它的前往類型。Executors類供給了一些有效的辦法去在線程池中履行Callable內的義務。因為Callable義務是並行的,我們必需期待它前往的成果。java.util.concurrent.Future對象為我們處理了這個成績。在線程池提交Callable義務後前往了一個Future對象,應用它我們可以曉得Callable義務的狀況和獲得Callable前往的履行成果。Future供給了get()辦法讓我們可以期待Callable停止並獲得它的履行成果。

6. 甚麼是FutureTask?
FutureTask是Future的一個基本完成,我們可以將它同Executors應用處置異步義務。平日我們不須要應用FutureTask類,單當我們盤算重寫Future接口的一些辦法並堅持本來基本的完成是,它就變得異常有效。我們可以僅僅繼續於它偏重寫我們須要的辦法。

7.甚麼是並發容器的完成?
Java聚集類都是疾速掉敗的,這就意味著當聚集被轉變且一個線程在應用迭代器遍歷聚集的時刻,迭代器的next()辦法將拋出ConcurrentModificationException異常。

並發容器支撐並發的遍歷和並發的更新。

重要的類有ConcurrentHashMap, CopyOnWriteArrayList 和CopyOnWriteArraySet,浏覽這篇文章懂得若何防止ConcurrentModificationException。

8. Executors類是甚麼?
Executors為Executor,ExecutorService,ScheduledExecutorService,ThreadFactory和Callable類供給了一些對象辦法。

Executors可以用於便利的創立線程池。

其實java基本面試題遠不止這些,年夜家可以停止體系整頓。

願望年夜家面試勝利!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved