面試題之併發相關專欄三

一、ReentrantLock是如何實現可重入的?

ReentrantLock內部自定義了同步器Sync,其實就是加鎖的時候通過CAS算法,將線程對象放到一個雙向鏈表中,每次獲取鎖的時候,看下當前維護的那個線程ID和當前請求的線程ID是否一樣,一樣就可重入。

二、請說說CyclicBarrier和CountDownLatch的異同?

  •  CountDownLatch 是不可以重置的,所以無法重複使用,而CyclicBarrier可以重複使用柵欄;
  • CountDownLatch目的是讓一個線程等待其他N個線程達到某個條件後,自己再去做某個事情;而CyclicBarrier的目的是讓N多個線程互相等待直到所有線程都達到某個狀態,這N個線程再繼續執行各自後續操作;

三、爲什麼要用線程池?Java線程池的好處?

  • 重用已經存在的線程,減少了線程的創建和銷燬的開銷;
  • 可有效控制最大併發的線程數,提高了系統資源的使用率避免很多競爭,避免了OOM、死鎖等;
  • 可以提供定時和定期的執行方式,單線程,併發數量的控制等功能;

四、Java中線程池的種類?

  • newFixedThreadPool(int nThreads)      //啓動固定線程數的線程池
  • newCachedThreadPool()    //按需分配的線程池
  • newSingleThreadExecutor()    //單個線程的線程池
  • ScheduledThreadPoolExecutor()    //定時,定期執行任務的線程池
  • ThreadPoolExecutor()   //指定線程數的線程池

五、請談談ThreadPoolExecutor線程池的幾個核心參數?

  • 【1】corePoolSize:線程池中的常駐核心線程的數量(總線程量可大於等於這個值);
  • 【2】maximumPoolSize:線程池中能夠容納同時執行的最大線程數,此值必須大於等於1(總線程量不可能超越這個數值);
  • 【3】keepAliveTime:多餘的空閒線程的存活時間。當前池中線程數量超過corePoolSize時,當空閒時間達到keepAliveTime時,多餘線程會被銷燬直到只剩下corePoolSize個線程爲止;
  • 【4】unit:keepAliveTime的時間單位;
  • 【5】workQueue:任務隊列,被提交但尚未被執行的任務;例如: 提交了10個任務,但是線程只有5個,於是另外5個提交但沒開始執行的任務就存放到了workQueue工作隊列裏面,既然是隊列,我們知道,實現隊列的方式有很多種,比如ArrayBlockQueue、LinkedBlockQueue等等,選擇不同的隊列就會帶來不同的問題;
  1.     ArrayBlockQueue:存在一個任務過多超出隊列長度
  2.     LinkedBlockQueue:接受過多的任務可能會佔用太多內存,造成內存崩潰;
  • 【6】threadFactory:表示生成線程池中工作線程的線程工廠,用於創建線程,一般使用默認的線程工廠即可
  • 【7】handler:拒絕策略,表示當隊列滿了,並且工作線程大於等於線程池的最大線程數(maximumPoolSize)時如何來拒絕請求執行的runnable的策略。默認拒絕策略是AbortPolicy,拋出異常阻止程序
  1.  AbortPolicy:默認的拒絕策略,當提交的任務數量大於線程池中的最大數量時,會拋出RejectedExecutionException,阻止系統正常運行。
  2.     DiscardPolicy:該策略默默地丟棄無法處理的任務,不予任何處理也不拋出異常,如果允許任務丟失,這是最好的一種策略(什麼也不做,直接忽略).
  3.     DiscardOldestPolicy:拋棄隊列中等待最久的任務,然後把當前任務加入隊列中,嘗試再次提交當前任務(丟棄執行隊列中最老的任務,嘗試爲當前提交的任務騰出位置)
  4.     CallerRunsPolicy:“調用者運行”一種調節機制,該策略既不會拋棄任務,也不會拋出異常,而是將某些任務回退到調用者,從而降低新任務的流量(直接由提交任務者執行這個任務)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章