多線程(相關面試題)

1.多線程有什麼用?

1).發揮多核CPU的優勢。單核CPU上所謂的"多線程"是假的多線程,同一時間處理器只會處理一段邏輯,只不過線程之間切換得比較快,看着像多個線程"同時"運行。多核CPU上的多線程纔是真正的多線程,它能讓多段邏輯同時工作。

2)防止阻塞

3)便於建模

2.創建多線程的方式?

1)繼承Thread類

2)實現Runnable接口

因爲Java只支持單繼承,而接口可以多實現。

3)實現Callable接口

通過實現Callable接口並重寫call方法,並把Callable實例傳給FutureTask對象,再把FutureTask對象傳給Thread對象

3.start()方法和run()方法的區別?

啓動一個線程是調用start()方法,run()方法可以產生必須退出的標誌來停止一個線程。

只有調用了start()方法,纔會表現出多線程的特性,不同線程的run()方法裏面的代碼交替執行。如果只是調用了

run()方法,那麼代碼還是同步執行的,必須等待一個線程的run()方法裏面的代碼全部執行完,另一個線程纔可以執行

其run()方法裏面的代碼。

4.Runnable接口和Callable接口的區別?

Runnable接口中的run()方法的返回值是void,它做的事情只是純粹地去執行run()方法中的代碼而已;Callable接口

中的call()方法是有返回值的,是一個泛型,和Futrue、FutrueTask配合可以用來獲取異步的結果。

特性:多線程相比單線程更難、更復雜的一個重要原因就是多線程充滿着未知性

5.CyclicBarrier和CountDownLatch的區別?

都是java.util.concurrent下。

1)CyclicBarrier的某個線程運行到某個點上之後,該線程即停止運行,直到所有的線程都達到這個點,所有線程才重新運行。

  CountDownLatch則不是,某線程運行到某個點上之後,只是給某個數值-1而已,該線程繼續運行。

2)CyclicBarrier只能喚起一個任務,CountDownLatch可以喚起多個任務。

3)CyclicBarrier可重用,CountDownLatch不可重用,計數值爲0該CountDownLatch就不可再用。

6.volatile關鍵字作用?(不懂)

1)多線程主要圍繞可見性和原子性兩個特性而展開,使用volatile關鍵字修飾的變量,保證了其在多線程之間的可見性,即每次讀到volatile變量,一定是最新的數據。

2)和CAS結合,保證了原子性。

使用volatile關鍵字:1.對變量的寫操作不依賴當前變量的值   2.該變量沒有包含在其他變量的不變式中。

7.什麼是線程安全?

1)不可變

像String、Integer、Long 這些都是final類型的類,任何一個線程都改變不了他們的值

2)絕對線程安全

不管運行時環境如何,調用者都不需要額外的同步措施。

3)相對線程安全

像Vector這種,add、remove方法都是原子操作,不會被打斷,也就是fail_fast機制(不懂)

8.Java中如何獲取到線程dump文件(不懂)

死循環、死鎖、阻塞、頁面打開快慢等問題,線程dump是最好解決問題的路徑。所謂的dump也就是線程堆棧,獲取到線程堆棧

有兩步:

1)獲取線程的pid,可以通過使用jps命令,在Linux環境下還可以使用ps -ef |  grep  java

2)打印線程堆棧,可以通過使用jstack  pid 命令,在Linux環境下還可以使用 kill  -3 pid

另外,Thread類提供了一個getStackTrace()方法也可以獲取線程堆棧。

9.一個線程如果出現了運行時異常會怎麼樣?

如果這個異常沒有被捕獲的話,這個線程就停止執行了。另外重要的一點:如果這個線程持有某個對象的監視器,那麼這個對象監視器會被立即釋放。

10.如何在兩個線程之間共享數據?

通過在線程之間共享對象就Ok,然後通過wait/notify/notifyAll      await/singal/singalAll進行喚起和等待,比方說阻塞隊列

BlockingQueue就是爲了線程之間共享數據而設計的。

11.sleep方法和wait方法有什麼區別?

1)sleep來自Thead類,wait來自Object類

2)sleep方法沒有釋放鎖,而wait方法釋放了鎖。

3)如果線程持有某個對象的監視器,sleep方法不會放棄這個對象的監視器,wait方法會放棄這個對象的監視器(不懂)

12.生產者消費者模型的作用是什麼?(不懂)

1)通過平衡生產者的生產能力和消費者的消費能來提升整個系統的運行效率,這是生產者消費者模型最重要的作用。

2)解耦,這是生產者模型附帶的作用,解耦意味着生產者和消費者之間的聯繫少,聯繫越少越可以獨自發展而不需要收到相互的制約

13.ThreadLocal有什麼用?(不懂)

簡單說ThreadLocal就是一種以空間換時間的做法,把數據進行隔離,數據不共享,自然沒有線程安全方面的問題了。

14.爲什麼wait()方法和notify()/nofityAll()方法要在同步快中被調用?

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

15.wait()方法和notify()/notifyAll()方法在放棄對象監視器時有什麼區別?

wait()方法和notify()/notifyAll()方法在放棄對象監視器的時候區別在於:wait()方法立即釋放對象監視器,notify()/notifyAll()方法則會等待線程剩餘的代碼執行完畢纔會放棄對象監視器。

16.爲什麼使用線程池?

避免頻繁地創建和銷燬線程,達到線程對象的重用。

17.怎麼檢測一個線程是否持有對象監視器?(不懂)

Thread類提供了一個holdsLock(Object   obj)方法,當且僅當對象obj的監視器被某條線程的持有的時候纔會返回true,注意這是一個static方法,這意味着"某條線程"指的是當前線程。

18.synchronized和ReentrantLock的區別?(不懂)

synchronized是和if、else、for、while一樣的關鍵字,ReentrantLock是類,這是二者的本質區別。

1)ReentrantLock可以對獲取鎖的等待時間進行設置,這樣就避免了死鎖。

2)ReentrantLock可以獲取各種鎖的信息

3)ReentrantLock可以靈活地實現多路通知,另外,二者的鎖機制其實也是不一樣的。

19.ConcurrentHashMap的併發度是什麼?

ConcurrentHashMap的併發度就是segment的大小,默認爲16,這意味着最多同時可以有16 條線程操作ConcurrentHashMap,這也是ConcurrentHashMap對HashTable的最大優勢。

20.ReadWriteLock是什麼?

ReadWriteLock是一個讀寫鎖接口,ReentrantReadWriteLock是ReadWriteLock接口的一個具體實現,實現了讀寫分離,讀鎖是共享的,寫鎖是獨佔的。讀和讀之間不會互斥,讀和寫、寫和讀、寫和寫之間纔會互斥,提升了讀寫的性能。

21.FutureTask是什麼?(不懂)

FutureTask表示一個異步運算的任務,FutureTask裏面可以傳一個Callable的具體實現類。

22.Linux環境下如何查找哪個線程使用CPU最長?

1)獲取項目的pid,jps或者ps -ef | grep java,

2)top -H  -p  pid ,順序不能改變。(打印當前的項目,每條線程佔用CPU時間的百分比。)

23.Java編程寫一個會導致死鎖的程序?

1)兩個線程裏面分別持有兩個Object對象:lock1和lock2.這兩個lock作爲同步代碼塊的鎖。

2)線程1的run()方法中同步代碼先獲取lock1的對象鎖,Thread.sleep(xxx),然後接着獲取lock2的對象鎖。

3)線程2的run()方法中同步代碼塊先獲取lock2的對象鎖,接着獲取lock1的對象鎖

24.怎麼喚醒一個阻塞的線程?

如果線程是因爲調用了wait()、sleep()或者join()方法而導致的阻塞,可以中斷線程,並且通過拋出InterruptedException來喚醒它,無能爲力,因爲IO是操作系統實現的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章