1. 程式人生 > >JUC框架部分小結

JUC框架部分小結

ConcurrentHashMap:

  • 底層結構和HashMap是相同的。繼承自ConcurrentMap,AbstractMap以及序列化介面內部類主要有Node類以及Traverser類,CollectionView類。Node用於儲存鍵值對,有子類ForwardingNode以及TreeBin類,ReservationNode類以及TreeBin類。Traverser類主要用於遍歷操作。CollectionView的子類keySetView,ValueSetView分別用來表示鍵檢視以及值檢視
  • ConcurrenthashMap在進行putVal的時候會先去單獨的桶中的節點進行加鎖,而不是多整個map結構來進行加鎖。這樣鎖的粒度就變得比較小,不同桶之間的操作互補影響,其速度比上Hashtable以及通過Collections.SynchronizedMap生成的同步集合要快上不少
  • ConcurrentHashMap在進行節點操作以及相應的put之後增加節點數量統計的操作的時候使用到了大量的CAS操作。對摸一個桶的加鎖操作通過Synchronized()塊來實現

ConcurrentSkipListMap

  • 底層樹結構實現是跳錶,跳錶的插入和刪除操作時間複雜度都是O(lgn),其操作方式類似於二分查詢。
    內部類主要分為Index,HeadIndex以及Node這三個類。HeadIndex是跳錶的第一行,Index在中間,都擁有向下以及向右節點。ConcurrentSkipListMap在新增或者刪除右側,下側元素的時候使用了CAS操作。
    Node節點位域最底層,只有向後的連線點,用於組成單鏈表。
  • 跳錶中大量使用了CAS操作,在存放一個值的時候,首先通過跳錶向右或者向下找到待插入的前面節點,找到之後通過CAS插入,如果前去節點不是之前記錄的前去節點,說明在待插入的過程中又有其他的的節點插入到前驅節點之後。那麼重新開始查詢前驅節點。插入之後來檢測是否需要進行層級的增加。
    跳錶的刪除操作並不是立即刪除的,其做法是在待刪除節點後面新增一個Mark節點,然後將該節點從主鏈上斷開。下次遍歷的時候憑藉這個mark節點來刪除這個節點。

ArrayBlockingQueue

  • ArrayBlockingQueue的底層資料結構是陣列, 對陣列的訪問添加了鎖的機制,使其能夠支援多執行緒併發。
    繼承了AbstractQueue抽象類,繼承 佇列的基本操作,然後實現了BlockingQueue介面。
    內部實際上是由ReenTranLock以及兩個
    LinkedBlockingQueue
    底層採用的是連結串列結構,繼承了AbstractQueue,實現了BlockingQueue介面,BlockingQueue表示阻塞型的佇列,其對佇列的操作可能會丟擲異常;同時也實現了Searializable介面,表示可以被序列化。他繼承的東西和ArrayBlockingQueue相同
    內部包含兩把ReenTranlock,用於實現讀寫分離。非別有fullCondition以及emptyCondition.
    佇列如果容量達到了最大值,put函式會在條件notFull上等待,否則執行完成之後會喚醒在notFull條件上等待的執行緒。由於分別使用兩把Reentranlock,一把用於讀,一把用於寫,對隊列當前元素數量的統計使用AtomicInteger來實現
    一般有4個操作,put,take,offer,poll,後兩者的特點是不會丟擲中斷異常。
    當需要刪除節點的時候,會首先獲取讀寫鎖(防止此時出入佇列),然後遍歷,尋找到指定的節點刪除。

ConcurrentLinkedQueue

ConcurrentLinkedQueue不允許有null元素,與LinkBlockingQueue使用的都是相同的,都是連結串列結構。
同樣擁有內部節點類Node,通過cas操作保證操作的原子性。
poll以及offer函式都是使用cas操作來保證原子性,(相當於樂觀鎖)。remove(刪除摸個節點)也是相同的
注意ConcurrentLinkedQueue為空的時候,取元素操作不會被阻塞,而是直接返回一個null值。

CopyOnWriteArrayList

CopyOnWriteArrayList是ArrayList 的一個執行緒安全的變體,其中所有可變操作(add、set 等等)都是通過對底層陣列進行一次新的複製來實現的。其底層使用陣列來存放元素
COWIterator是CopyOnWriteArrayList的攜帶起,其內部有一個Object型別的陣列作為CopyOnWriteArrayList陣列的快照,這種快照風格的迭代器方法在建立迭代器時使用了對當時陣列狀態的引用。此陣列在迭代器的生存期內不會更改,因此不可能發生衝突,
建立迭代器以後,迭代器就不會反映列表的新增、移除或者更改。在迭代器上進行的元素更改操作(remove、set 和 add)不受支援
新增刪除操作是通過寫時複製實現的,add先加鎖,然後複製一份長度為len+1的陣列,然後將elements新增到最後的位子,再將CopyOnWriteArrayList的陣列用這個新陣列替換掉。set(設定某個Index上的元素)一樣,也通過寫時複製實現
當一邊網COWArrayList中新增元素,一邊通過迭代遍歷的時候,實際上不會訪問真正當前的陣列,而只是訪問迭代器中的快照。

CopyOnWriteArraySet

底層實際上採用的是前面的CopyOnWriteArrayList,最為一個內部類
內部所有的操作都轉換為CowArrayList操作實現,通過其addAbsent來實現,也就是不允許元素的重複

ConcurrentSkipListSet

底層基於ConcurrentSkipListMap來實現
並且迭代器是弱一致性的,即在迭代的過程中,可以有其他修改ConcurrentSkipListSet的操作,不會丟擲ConcurrentModificationException異常

ThreadPoolExecutor

ThreadPoolExecutor內部主要由BlockingQueue和AbstractQueuedSynchronizer提供支援,繼承自AbstractExecutorService,AbstractExecuetorService提供了ExecutorService執行方法的預設實現。
內部的主要類包括一個Worker類(繼承自AQS,實現了Runnable),內部包含Runnable物件以及Thread屬性。thread屬性的通過ThreadFactory來對其初始化,然後通過AQS來設定獨佔執行緒。
ThreadPoolExecutor有一個Atomic的ctl屬性,高三位表明了執行緒池的狀態,低29位表示了執行的worker數量。
執行緒池在飽和情況或者是shutDown情況下的時候實際上會拒絕任務的,然後會呼叫構造執行緒池時候的飽和函式。執行緒池會不斷的將使用者的任務封裝成worker,然後將worker新增到worker集合中去。
每次執行一個Worker的時候,實際上會對會將WOrker加鎖鎖起來
執行緒被submit到執行緒池的時候就會被提交執行,當遞交的RUnnable數量唱過執行緒池容量,Runnable會進入阻塞佇列,LinkedBlockingQueue,當執行緒池Worker執行緒有空閒的時候會去除阻塞佇列中的worker執行
Worker執行緒沒沒取得對應的Runable執行緒的時候,對LinkedBlockingQueue的take操作(也就是取使用者任務)會阻塞住。執行執行緒池的shutDown會中斷這些阻塞的Worker執行緒。
corePoolSize執行的執行緒少於 corePoolSize,則建立==新執行緒==來處理請求,即使其他已建立的執行緒是空閒的。
maxPoolSize:使用者任務(Runnable)阻塞佇列的大小。
表示曾經同時存在線上程池的worker的大小,為workers集合的最大大小。
當阻塞佇列無法新增Runnable的時候,執行緒池會拒絕任務,呼叫拒絕任務處理函式
shutdown會設定執行緒池的執行狀態為SHUTDOWN,並且中斷所有空閒的worker,由於worker執行時會進行相應的檢查,所以之後會退出執行緒池,並且其會繼續執行之前提交到阻塞佇列中的任務,不再接受新任務。shutdownNow則會設定執行緒池的執行狀態為STOP,並且中斷所有的執行緒(包括空閒和正在執行的執行緒),在阻塞佇列中的任務將不會被執行,並且會將其轉化為List返回給呼叫者
執行緒池通過減少每次做任務的時候產生的效能消耗來優化執行大量的非同步任務的時候的系統性能。執行緒池還提供了限制和管理批量任務被執行的時候消耗的資源、執行緒的方法。另外ThreadPoolExecutor還提供了簡單的統計功能,比如當前有多少任務被執行完了。
ThreadPoolExecutor提供了protected型別可以被覆蓋的鉤子方法,允許使用者在任務執行之前會執行之後做一些事情。我們可以通過它來實現比如初始化ThreadLocal、收集統計資訊、如記錄日誌等操作。這類Hook如beforeExecute和afterExecute。另外還有一個Hook可以用來在任務被執行完的時候讓使用者插入邏輯,如rerminated。
偏向鎖

AQS的CAS操作實際上是樂觀鎖,而偏向鎖實際上會偏向於獲取他的執行緒,其在無競爭的情況下把整個同步都消除掉,連CAS操作都不做了。鎖偏向於第一個獲得它的執行緒。如果在接下來的執行過程中,該鎖沒有被其他的執行緒獲取,則持有偏向鎖的執行緒將永遠不需要再進行同步
關於無鎖

講到無鎖,必然是Disruptor併發框架,Disruptor底層依賴一個RingBuffer來進行執行緒之間的資料交換。多執行緒對RingBuffer的讀和寫不會涉及到鎖,然而因為RingBuffer滿或者RingBuffer中沒有可消費內容引發的執行緒等待,那就要另當別論了。

簡單幾句介紹下無鎖原理,RingBuffer維護者可讀和可寫的指標,也叫遊標,它指向生產者或消費者需要寫或讀的位置,而對於指標的更新是由CAS來完成的,這個過程中我們不需要加鎖/解鎖的過程。
使用到Future或者FutureTask應該注意到的問題:

任務超時時間,一方面我們不能夠無限期的佔用執行緒資源,另一方面我們不能夠讓外部無限期的等待,因此timeout變得尤為重要。

主動取消任務,假如我們覺得timeout不夠靈活,通常場景是當我們在timeout之前已經知道FutureTask不需要再繼續為我們工作的時候,我們可以先判斷任務是否已經done(isDone),如果沒有done,我們可以主動的將任務取消掉,這個時候Future定義的cancel可以派上用場。

任務異常資訊,還記得我們最初提交的Runnable和Callable麼,當任務丟擲了異常我們如何get到異常資訊呢,FutureTask其實是代理了Runnable和Callable的執行,捕獲異常並將異常資訊交給outcome,因此通過FutureTask,我們同樣可以獲得任務內部丟擲的異常資訊。

相關推薦

JUC框架部分小結

ConcurrentHashMap: 底層結構和HashMap是相同的。繼承自ConcurrentMap,AbstractMap以及序列化介面內部類主要有Node類以及Traverser類,CollectionView類。Node用於儲存鍵值對,有子類For

java面試⑥框架部分

nat ecb ring 5.7 截器 框架 5.4 iba cbe 2.5.1 什麽是框架: 2.5.2 MVC模式 2.5.3 MVC框架 2.5.4 簡單講一下struts2的執行流程 2.5.5 Struts2中的攔截器,你都用它幹什麽?

面試題 ------ 框架部分

1、什麼事框架? 框架(Framework)是一個框架————指約束性,也是一個架子————指器支撐性 IT 語境中的框架,特指為解決一個開放性問題而設計得具有一定約束性的支撐結構,在此結構上可以根據具體問題擴充套件、安插更多的組成部分,從而更迅速和方便地構建完整的解決

MySQL 部分小結

資料庫概述 資料(Data) 對於計算機來說,資料就是計算機儲存的(有用的)資訊。既然是計算機儲存的,那麼實質上它就是一串二進位制資料(0、1),但是人始終還是要用這個資訊的,所以資料儲存不能是毫無章法的,它必須遵循一定的規則,資料格式定義了這種規則。 我們之前說過的資料型別就是一種資料

Java框架部分---面試題

說說Spring? Spring的核心是控制反轉、依賴注入,Aop(面向切面)相當於把每個bean與bean之間的關係交給第 三方容器進行管理. 說SpringIOC、SpringAOP? SpringIOC ,其實就是依賴注入、控制反轉。相當於把每個bean與bean之間的關係交給第三方容器管理。而這

Java 併發程式設計實戰 第一部分小結

下列"併發技巧清單" 列舉了第一部分介紹的概念和規則 * 可變狀態是直觀重要的(it's mutable state, stupid)     所有的併發問題都可以歸結為如何協調對併發狀態的訪問,可變狀態越少,就越容易確保執行緒的安全性。 * 儘量將域宣告為fina

spring/ibatis框架部分解析(TODO)

spring/ibatis框架部分解析(TODO) 歡迎使用Markdown編輯器 新的改變 功能快捷鍵 合理的建立標題,有助於目錄的生成 如何改變文字的樣式 插入連結與圖片 如何插入一段漂亮的程式碼片 生

shiro框架使用小結

1授予許可權 命名規則(推薦方式): 使用者角色:資源名:可執行操作名 比如sys:dept:save表示擁有sys角色的使用者擁有對資源dept進行save操作的許可權,如要設定擁有多重許可權,則用逗號分隔:sys:dept:save,delete;如果需要擁有所有許可權,則用萬用字元

代數部分小結

代數部分小結 問題:正整數集合N,最多有數字1000個,給定一個正整數K 從N中取任意個數字相加,和為SUM,SUM不大於K 求SUM可以達到的最大值 題解:這是一個比較典型的01揹包問題,可以用動態規劃的方法來解決. 首先,對問題進行一點小小的變形,即將K看做揹包容量v,而每一個集合中的數字,看作

DRF 框架學習小結

前言: django restful framework框架,繼續學習中。發現了一篇不錯的文章。 1、 RESTful是一種API的命名風格。 2、 前後端分離: 使用者訪問靜態檔案的伺服器,資料全部由ajax請求給到。 3、 RESTful風格:資料應該是名詞,而動詞

[RK3288][Android6.0] PMIC之RK818硬體部分小結

電源分類: 主要分兩種: DC/DC 和 LDO, 兩種特性如下: DC/DC: 即直流變壓器.分buck(降壓),boost(升壓),buck-boost(升降壓).效率高,成本高,大電流使用,不過

RF框架簡介小結

Robot Framework使用簡單,類庫豐富,還可以自由開發系統關鍵字。 Robot Framework特點: l 使用簡單l 非常豐富的庫l 可以像程式設計一樣寫測試用例l 支援開發系統關鍵字  1、使用簡單。當你真的要向專案中推廣一個技術或工具的時候,其實這點非

高通平臺Camera框架部分淺談--Camera C/S 的init流程

       瞭解的不夠深入,應用功能實現後,再回頭細看Camera框架時,還是有些地方沒能連通,在網上也找了一些文章結合程式碼來分析,不過能力有限,甚是痛苦。而且由於平臺不同,程式碼的具體流程還是有區別。       下

laravel 框架部分細節記錄

laravel5 只能夠使用根目錄下的server.php訪問,需要開啟Apache下的mod_rewrite模組,才能正常使用。 關於去除public目錄的問題,httpd.conf中 DocumentRoot "c:/wamp/www/" 改為 DocumentRoot

Spring AOP框架體系小結

一、這裡先列舉一些AOP基本概念,後面提到再作相應解釋1)目標物件 target2)代理物件 proxy3)切點 pointcut4)增強 advice5)切面 advisor6)織入器:將增強邏輯嵌入

AbstractQueuedSynchronizer(AQS)抽絲剝繭深入瞭解JUC框架原理

[TOC] # 簡介 AQS(AbstractQueuedSynchronizer)是併發開發中一個基礎元件。主要實現了同步狀態管理、執行緒佇列管理、執行緒等待、執行緒喚醒等底層操作。JDK中許多的併發類都是依賴AQS的。 ReentrantLock(可重入鎖)、Semaphore(訊號量)、CountD

Java開發工程師最新面試題庫系列——Mybatis框架部分(附答案)

##### Mybatis 1. Mybatis是什麼框架? 答:持久層框架 2. Mybatis和ORM有什麼區別? 答:ORM是物件關係對映的一種設計理念,也就是物件屬性對應資料庫欄位,讓開發人員以操作物件的方式操作資料庫資料。Mybatis是基於ORM框架實現的持久層框架,但它並是不

首選項框架PreferenceFragment部分源代碼分析

mit 系統 repl 原理 網絡 intern popu todo array 由於要改一些settings裏面的bug以及之前在裏面有做過勿擾模式,準備對勿擾模式做一個總結,那先分析一下settings的源代碼,裏面的核心應該就是android3.0 上

Linux內核中網絡數據包的接收-第一部分 概念和框架

csdn 請求 版本號 post sched nec alloc nts 多核cpu 與網絡數據包的發送不同,網絡收包是異步的的。由於你不確定誰會在什麽時候突然發一個網絡包給你。因此這個網絡收包邏輯事實上包括兩件事:1.數據包到來後的通知2.收到通知並從數據包中獲取數據

Mybatis框架之動態SQL書寫方式小結

用戶輸入 ... pre efi date emp 表達式 內容 字符 動態SQL簡介 動態SQL是Mybatis框架中強大特性之一。在一些組合查詢頁面,需要根據用戶輸入的查詢條件生成不同的查詢SQL,這在JDBC或其他相似框架中需要在代碼中拼寫SQL,經常容易出錯,在My