Android 面試之 Java 併發

在這裏插入圖片描述
Java 併發中考察頻率較高的有線程、線程池、鎖、線程間的等待和喚醒、線程特性和阻塞隊列等。

線程

1. 線程的狀態有哪些?
參考回答:

  • new:新創建的線程
  • Ready:準備就緒的線程,由於CPU分配的時間片的關係,此時的任務不在執行過程中。
  • Running:正在執行的任務
  • Block:被阻塞的任務
  • Time Waiting:計時等待的任務
  • Terminated:終止的任務

2. 線程中wait和sleep的區別?
參考回答:
wait方法既釋放cpu,又釋放鎖。
sleep方法只釋放cpu,但是不釋放鎖。

3. 線程和進程的區別?
參考回答:
線程是CPU調度的最小單位,一個進程中可以包含多個線程,在Android中,一個進程通常是一個App,App中會有一個主線程,主線程可以用來操作界面元素,如果有耗時的操作,必須開啓子線程執行,不然會出現ANR,除此以外,進程間的數據是獨立的,線程間的數據可以共享。

線程池

4. 與新建一個線程相比,線程池的特點?
參考回答:

  • 節省開銷: 線程池中的線程可以重複利用。
  • 速度快:任務來了就能開始,省去創建線程的時間。
  • 線程可控:線程數量可空和任務可控。
  • 功能強大:可以定時和重複執行任務。

5. 線程池中的幾個參數是什麼意思,線程池的種類有哪些?
參考回答:
線程池的構造函數如下:

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
}

參數解釋如下:

  • corePoolSize:核心線程數量,不會釋放。
  • maximumPoolSize:允許使用的最大線程池數量,非核心線程數量,閒置時會釋放。
  • keepAliveTime:閒置線程允許的最大閒置時間。
  • unit:閒置時間的單位。
  • workQueue:阻塞隊列,不同的阻塞隊列有不同的特性。

線程池分爲四個類型:

  • CachedThreadPool:閒置線程超時會釋放,沒有閒置線程的情況下,每次都會創建新的線程。
  • FixedThreadPool:線程池只能存放指定數量的線程池,線程不會釋放,可重複利用。
  • SingleThreadExecutor:單線程的線程池。
  • ScheduledThreadPool:可定時和重複執行的線程池。
  1. 線程池的工作流程?
    參考回答:

7. 死鎖觸發的四大條件?
參考回答:

  • 互斥鎖
  • 請求與保持
  • 不可剝奪
  • 循環的請求與等待

8. synchronized和Lock的區別?
參考回答:

  • synchronized是Java中的關鍵字,是Java的內置實現;Lock是Java中的接口。
  • synchronized遇到異常會釋放鎖;Lock需要在發生異常的時候調用成員方法Lock#unlock()方法。
  • synchronized是不可以中斷的,Lock可中斷。
  • synchronized不能去嘗試獲得鎖,沒有獲得鎖就會被阻塞; Lock可以去嘗試獲得鎖,如果未獲得可以嘗試處理其他邏輯。
  • synchronized多線程效率不如Lock,不過Java在1.6以後已經對synchronized進行大量的優化,所以性能上來講,其實差不了多少。

線程間通信

9. notify和notifyAll方法的區別?
參考回答:
notify隨機喚醒一個線程,notifyAll喚醒所有等待的線程,讓他們競爭鎖。

10. volatile的原理?
參考回答:

  • 可見性
    如果對聲明瞭volatile的變量進行寫操作的時候,JVM會向處理器發送一條Lock前綴的指令,將這個變量所在緩存行的數據寫入到系統內存。

多處理器的環境下,其他處理器的緩存還是舊的,爲了保證各個處理器一致,會通過嗅探在總線上傳播的數據來檢測自己的數據是否過期,如果過期,會強制重新將系統內存的數據讀取到處理器緩存。

  • 有序性
    Lock前綴的指令相當於一個內存柵欄,它確保指令排序的時候,不會把後面的指令拍到內存柵欄的前面,也不會把前面的指令排到內存柵欄的後面。

阻塞隊列

11. ConcurrentHashMap的原理?
參考回答:
數據結構的實現跟HashMap一樣,不做介紹。

JDK 1.8之前採用的是分段鎖,核心類是一個Segment,Segment繼承了ReentrantLock,每個Segment對象管理若干個桶,多個線程訪問同一個元素的時候只能去競爭獲取鎖。

JDK 1.8採用了CAS + synchronized,插入鍵值對的時候如果當前桶中沒有Node節點,使用CAS方式進行更新,如果有Node節點,則使用synchronized的方式進行更新。

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