慕課網實戰·高併發探索(九):併發容器 J.U.C
特別感謝:慕課網jimin老師的《Java併發程式設計與高併發解決方案》課程,以下知識點多數來自老師的課程內容。
jimin老師課程地址:Java併發程式設計與高併發解決方案
概述
Java併發容器JUC是三個單詞的縮寫。是JDK下面的一個包名。即Java.util.concurrency。
上一節我們介紹了ArrayList、HashMap、HashSet對應的同步容器保證其執行緒安全,這節我們介紹一下其對應的併發容器。
ArrayList –> CopyOnWriteArrayList
CopyOnWriteArrayList 寫操作時複製,當有新元素新增到集合中時,從原有的陣列中拷貝一份出來,然後在新的陣列上作寫操作,將原來的陣列指向新的陣列。整個陣列的add操作都是在鎖的保護下進行的,防止併發時複製多份副本。讀操作是在原陣列中進行,不需要加鎖
缺點:
1.寫操作時複製消耗記憶體,如果元素比較多時候,容易導致young gc 和full gc。
2.不能用於實時讀的場景.由於複製和add操作等需要時間,故讀取時可能讀到舊值。
能做到最終一致性,但無法滿足實時性的要求,更適合讀多寫少的場景。
如果無法知道陣列有多大,或者add,set操作有多少,慎用此類,在大量的複製副本的過程中很容易出錯。設計思想:
1.讀寫分離
2.最終一致性
3.使用時另外開闢空間,防止併發衝突原始碼分析
//構造方法
public CopyOnWriteArrayList(Collection<? extends E> c) {
Object[] elements;//使用物件陣列來承載資料
if (c.getClass() == CopyOnWriteArrayList.class)
elements = ((CopyOnWriteArrayList<?>)c).getArray();
else {
elements = c.toArray();
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elements.getClass() != Object[].class)
elements = Arrays.copyOf(elements, elements.length, Object[].class);
}
setArray(elements);
}
//新增資料方法
public boolean add(E e) {
final ReentrantLock lock = this.lock;//使用重入鎖,保證執行緒安全
lock.lock();
try {
Object[] elements = getArray();//獲取當前陣列資料
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);//複製當前陣列並且擴容+1
newElements[len] = e;//將要新增的資料放入新陣列
setArray(newElements);//將原來的陣列指向新的陣列
return true;
} finally {
lock.unlock();
}
}
//獲取資料方法,與普通的get沒什麼差別
private E get(Object[] a, int index) {
return (E) a[index];
}
HashSet –> CopyOnWriteArraySet
- 它是執行緒安全的,底層實現使用的是CopyOnWriteArrayList,因此它也適用於大小很小的set集合,只讀操作遠大於可變操作。因為他需要copy整個陣列,所以包括add、remove、set它的開銷相對於大一些。
- 迭代器不支援可變的remove操作。使用迭代器遍歷的時候速度很快,而且不會與其他執行緒發生衝突。
- 原始碼分析:
//構造方法
public CopyOnWriteArraySet() {
al = new CopyOnWriteArrayList<E>();//底層使用CopyOnWriteArrayList
}
//新增元素方法,基本實現原理與CopyOnWriteArrayList相同
private boolean addIfAbsent(E e, Object[] snapshot) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] current = getArray();
int len = current.length;
if (snapshot != current) {//添加了元素去重操作
// Optimize for lost race to another addXXX operation
int common = Math.min(snapshot.length, len);
for (int i = 0; i < common; i++)
if (current[i] != snapshot[i] && eq(e, current[i]))
return false;
if (indexOf(e, current, common, len) >= 0)
return false;
}
Object[] newElements = Arrays.copyOf(current, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
TreeSet –> ConcurrentSkipListSet
它是JDK6新增的類,同TreeSet一樣支援自然排序,並且可以在構造的時候自己定義比較器。
- 同其他set集合,是基於map集合的(基於ConcurrentSkipListMap),在多執行緒環境下,裡面的contains、add、remove操作都是執行緒安全的。
- 多個執行緒可以安全的併發的執行插入、移除、和訪問操作。但是對於批量操作addAll、removeAll、retainAll和containsAll並不能保證以原子方式執行,原因是addAll、removeAll、retainAll底層呼叫的還是contains、add、remove方法,只能保證每一次的執行是原子性的,代表在單一執行操縱時不會被打斷,但是不能保證每一次批量操作都不會被打斷。在使用批量操作時,還是需要手動加上同步操作的。
- 不允許使用null元素的,它無法可靠的將引數及返回值與不存在的元素區分開來。
- 原始碼分析:
//構造方法
public ConcurrentSkipListSet() {
m = new ConcurrentSkipListMap<E,Object>();//使用ConcurrentSkipListMap實現
}
HashMap –> ConcurrentHashMap
- 不允許空值,在實際的應用中除了少數的插入操作和刪除操作外,絕大多數我們使用map都是讀取操作。而且讀操作大多數都是成功的。基於這個前提,它針對讀操作做了大量的優化。因此這個類在高併發環境下有特別好的表現。
- ConcurrentHashMap作為Concurrent一族,其有著高效地併發操作,相比Hashtable的笨重,ConcurrentHashMap則更勝一籌了。
- 在1.8版本以前,ConcurrentHashMap採用分段鎖的概念,使鎖更加細化,但是1.8已經改變了這種思路,而是利用CAS+Synchronized來保證併發更新的安全,當然底層採用陣列+連結串列+紅黑樹的儲存結構。
TreeMap –> ConcurrentSkipListMap
- 底層實現採用SkipList跳錶
- 曾經有人用ConcurrentHashMap與ConcurrentSkipListMap做效能測試,在4個執行緒1.6W的資料條件下,前者的資料存取速度是後者的4倍左右。但是後者有幾個前者不能比擬的優點:
1、Key是有序的
2、支援更高的併發,儲存時間與執行緒數無關
安全共享物件策略
- 執行緒限制:一個被執行緒限制的物件,由執行緒獨佔,並且只能被佔有它的執行緒修改
- 共享只讀:一個共享只讀的U帝鄉,在沒有額外同步的情況下,可以被多個執行緒併發訪問,但是任何執行緒都不能修改它
- 執行緒安全物件:一個執行緒安全的物件或者容器,在內部通過同步機制來保障執行緒安全,多以其他執行緒無需額外的同步就可以通過公共介面隨意訪問他
- 被守護物件:被守護物件只能通過獲取特定的鎖來訪問。
相關推薦
慕課網實戰·高併發探索(九):併發容器 J.U.C
特別感謝:慕課網jimin老師的《Java併發程式設計與高併發解決方案》課程,以下知識點多數來自老師的課程內容。 jimin老師課程地址:Java併發程式設計與高併發解決方案 概述 Java併發容器JUC是三個單詞的縮寫。是JDK下面的一個包名。
慕課網實戰·高併發探索(十四):執行緒池 Executor
特別感謝:慕課網jimin老師的《Java併發程式設計與高併發解決方案》課程,以下知識點多數來自老師的課程內容。 jimin老師課程地址:Java併發程式設計與高併發解決方案 new Thread的弊端 每次new Thread 新建物件,效能
慕課網實戰·高併發探索(七):執行緒封閉
特別感謝:慕課網jimin老師的《Java併發程式設計與高併發解決方案》課程,以下知識點多數來自老師的課程內容。 jimin老師課程地址:Java併發程式設計與高併發解決方案 1、什麼是執行緒封閉? 它其實就是把物件封裝到一個執行緒裡,只有一個執行緒能
慕課網實戰·高併發探索(四):執行緒安全性-可見性-有序性
可見性 什麼是可見性? 一個執行緒對主記憶體的修改可以及時的被其他執行緒觀察到 導致共享變數線上程間不可見的原因 執行緒交叉執行 重排序結合線程交叉執行 共享變數更新後的值沒有在工作記憶體與主存間及時更新 JVM處理可見性 J
慕課網實戰·高併發探索(十二):併發容器J.U.C -- AQS元件 鎖:ReentrantLock、ReentrantReadWriteLock、StempedLock
特別感謝:慕課網jimin老師的《Java併發程式設計與高併發解決方案》課程,以下知識點多數來自老師的課程內容。 jimin老師課程地址:Java併發程式設計與高併發解決方案 ReentrantLock java中有兩類鎖,一類是Synchron
【慕課網】JavaScript中OOP(上)
1.概念與繼承 面向物件程式設計(Object-oriented programming,OOP)是一種程式設計範型,同時也是一種程式開發的方法。物件指的是類的例項。它將物件作為程式的基本單元,將程式和資料封裝其中,以提高軟體的重用性、靈活性和擴充套件性。 面向物件特點:繼承、封
Python3《機器學習實戰》學習筆記(九):支援向量機實戰篇之再撕非線性SVM
一 前言 上篇文章講解的是線性SVM的推導過程以及簡化版SMO演算法的程式碼實現。本篇文章將講解SMO演算法的優化方法以及非線性SVM。 二 SMO演算法優化 在幾百個點組成的小規模資料集上,簡化版SMO演算法的執行是沒有什麼問題
2017.4.26 慕課網--Java 高併發秒殺API(一)
Java高併發秒殺API系列(一) -----------------業務分析及Dao層 第一章 課程介紹 1.1 內容介紹及業務分析 (1)課程內容 1 SSM框架的整合使用 2 秒殺類系統需求理解和實現 3 常用技術解決高併發問題 (
慕課網-java高併發秒殺api之高併發優化-總結
1.架構優化 2.spring宣告式事務 宣告式事務:http://www.open-open.com/lib/view/open1414310646012.html 配置並使用Spring宣告式事務 在spring-service.xml中新增上配置事務管理器 <
【慕課網實戰課程筆記】Vue.js高仿餓了麼外賣App
寫在前面:該課程為慕課網付費課程,筆記內容程式碼居多、內容簡略,僅供自己日後翻閱。如有疑問或者不妥,歡迎提出指正,我看到了會回覆,謝謝! 第1章:課程簡介 第2章:Vuejs介紹 Ctrl+Alt+l 快捷整理程式碼 第3章:Vue-cli開啟Vue
【慕課網實戰】Spark Streaming實時流處理項目實戰筆記三之銘文升級版
聚集 配置文件 ssi path fig rect 擴展 str 控制臺 銘文一級: Flume概述Flume is a distributed, reliable, and available service for efficiently collecting(收集),
【慕課網實戰】Spark Streaming實時流處理項目實戰筆記五之銘文升級版
環境變量 local server 節點數 replicas conn 配置環境 park 所有 銘文一級: 單節點單broker的部署及使用 $KAFKA_HOME/config/server.propertiesbroker.id=0listenershost.name
【慕課網實戰】Spark Streaming實時流處理項目實戰筆記九之銘文升級版
file sin ssi 右上角 result map tap 核心 內容 銘文一級: 核心概念:StreamingContext def this(sparkContext: SparkContext, batchDuration: Duration) = { th
【慕課網實戰】Spark Streaming實時流處理項目實戰筆記十之銘文升級版
state 分鐘 mooc 系統數據 使用 連接 var style stream 銘文一級: 第八章:Spark Streaming進階與案例實戰 updateStateByKey算子需求:統計到目前為止累積出現的單詞的個數(需要保持住以前的狀態) java.lang.I
【慕課網實戰】Spark Streaming實時流處理項目實戰筆記十五之銘文升級版
spa for 序列 html art mat div pre paths 銘文一級:[木有筆記] 銘文二級: 第12章 Spark Streaming項目實戰 行為日誌分析: 1.訪問量的統計 2.網站黏性 3.推薦 Python實時產生數據 訪問URL->IP
【慕課網實戰】Spark Streaming實時流處理項目實戰筆記十六之銘文升級版
.so zook orm 3.1 date nta highlight org 結果 銘文一級: linux crontab 網站:http://tool.lu/crontab 每一分鐘執行一次的crontab表達式: */1 * * * * crontab -e */1
【慕課網實戰】Spark Streaming實時流處理項目實戰筆記十七之銘文升級版
eid 實時 root 現在 ava == oop urn 啟動 銘文一級: 功能1:今天到現在為止 實戰課程 的訪問量 yyyyMMdd courseid 使用數據庫來進行存儲我們的統計結果 Spark Streaming把統計結果寫入到數據庫裏面 可視化前端根據:yyy
【慕課網實戰】Spark Streaming實時流處理項目實戰筆記二十之銘文升級版
.get frame 結果 取數據 lena echarts object 原理 四種 銘文一級: Spring Boot整合Echarts動態獲取HBase的數據1) 動態的傳遞進去當天的時間 a) 在代碼中寫死 b) 讓你查詢昨天的、前天的咋辦? 在頁面中放一個時間插
【慕課網實戰】Spark Streaming實時流處理項目實戰筆記二十一之銘文升級版
win7 小時 其他 har safari 北京 web 連接 rim 銘文一級: DataV功能說明1)點擊量分省排名/運營商訪問占比 Spark SQL項目實戰課程: 通過IP就能解析到省份、城市、運營商 2)瀏覽器訪問占比/操作系統占比 Hadoop項目:userAg
超多慕課網實戰教程破解自學教程百度雲盤分享-Python/Java/前端後端/小程序/運維測試/人工智能
上線 備註 面試 漏洞 vue ret 服務號 協作平臺 java軟件 以下課程,需要的可以加我微*信:hgh813210,備註你需要的課程 Java企業級電商項目架構演進之路 Tomcat集群與Redis分布式百度雲實戰分享 前端成長必經之路 基於Storm構建實時熱力分