1. 程式人生 > >Java集合的讀寫分離術--CopyOnWriteArrayList

Java集合的讀寫分離術--CopyOnWriteArrayList

 Copy-On-Write簡稱COW,是一種用於程式設計中的優化策略。其基本思路是,從一開始大家都在共享同一個內容,當某個人想要修改這個內容的時候,才會真正把內容Copy出去形成一個新的內容然後再改,這是一種延時懶惰策略。從JDK1.5開始Java併發包裡提供了兩個使用CopyOnWrite機制實現的併發容器,它們是CopyOnWriteArrayList和CopyOnWriteArraySet。CopyOnWrite容器非常有用,可以在非常多的併發場景中使用到。

什麼是CopyOnWrite容器

  CopyOnWrite容器即寫時複製的容器。通俗的理解是當我們往一個容器新增元素的時候,不直接往當前容器新增,而是先將當前容器進行Copy,複製出一個新的容器,然後新的容器裡新增元素,新增完元素之後,再將原容器的引用指向新的容器。這樣做的好處是我們可以對CopyOnWrite容器進行併發的讀,而不需要加鎖,因為當前容器不會新增任何元素。所以CopyOnWrite容器也是一種讀寫分離的思想,讀和寫不同的容器。

CopyOnWriteArrayList的實現原理

  在使用CopyOnWriteArrayList之前,我們先閱讀其原始碼瞭解下它是如何實現的。以下程式碼是向CopyOnWriteArrayList中add方法的實現(向CopyOnWriteArrayList裡新增元素),可以發現在新增的時候是需要加鎖的,否則多執行緒寫的時候會Copy出N個副本出來。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 /** * Appends the specified element to the end of this list. * * @param e element to be appended to this list * @return <tt>true</tt> (as specified by {@link Collection#add}) */ 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); newElements[len] = e; setArray(newElements); return true; finally { lock.unlock(); } }

   讀的時候不需要加鎖,如果讀的時候有多個執行緒正在向CopyOnWriteArrayList新增資料,讀還是會讀到舊的資料,因為寫的時候不會鎖住舊的CopyOnWriteArrayList。

1 2 3 public E get(int index) { return get(getArray(), index); }

   JDK中並沒有提供CopyOnWriteMap,我們可以參考CopyOnWriteArrayList來實現一個,基本程式碼如下:

相關推薦

Java集合分離--CopyOnWriteArrayList

 Copy-On-Write簡稱COW,是一種用於程式設計中的優化策略。其基本思路是,從一開始大家都在共享同一個內容,當某個人想要修改這個內容的時候,才會真正把內容Copy出去形成一個新的內容然後再改,這是一種延時懶惰策略。從JDK1.5開始Java併發包裡提供了兩個

MongoDB副本集組成成員以及利用java進行分離時可以選擇的引數

MongoDB副本集利用java進行讀寫分離時,引數有: primary:預設引數,只從主節點上進行讀取操作; primaryPreferred:大部分從主節點上讀取資料,只有主節點不可用時從secondary節點讀取資料。 secondary:只從secondary節點上進

Java實現分離

一前言                     在網際網路專案中,隨著業務的增加,訪問的增長,對系統性能,擴充套件性,伸縮性提出更高的同時,資料庫的壓力也陡然增加。越來越多的系統採用分散式系統架構,在資料方面,也採用資料庫叢集,與此同時,基於系統訪問,資料的查詢較多,增刪改

JAVA-mysql分離外掛介紹

kingshard kingshard是一個由Go開發高效能MySQL Proxy專案,kingshard在滿足基本的讀寫分離的功能上,致力於簡化MySQL分庫分表操作;能夠讓DBA通過kingshard輕鬆平滑地實現MySQL資料庫擴容。 kingshard的效能

java實現mysql數據庫分離之定義多數據源方式

修改 protect frame auto ret 更新數據 logs cannot initial 該示例是基於spring提供的AbstractRoutingDataSource,實現了一個動態數據源的功能,在spring配置中定義多個數據庫分為主、從數據庫,實現效

Java架構學習(三十)redis高階&redis高可用&主從複製&分離&叢集&哨兵機制&持久化RDB儲存&持久化AOF儲存&事務機制&Redis釋出訂閱

redis高階 一、基礎回顧 什麼是redis? 答:redis是非關係型資料庫,使用redis的目的是:減輕資料庫訪問壓力。 資料庫是做IO操作,使用redis是記憶體操作,記憶體資料庫, 效率要比IO效率高。這個就是快取。 如果資料庫值與redis

mongodb 分離以及java

mongod.exe --bind_ip 192.168.1.202 --port 50001 --logpath E:\MongoDB\logs\log.txt --logappend --dbpath E:\MongoDB\data\db --replSet zhang

Java實現資料庫的分離

引言 1、讀寫分離:可以通過Spring提供的AbstractRoutingDataSource類,重寫determineCurrentLookupKey方法,實現動態切換資料來源的功能;讀寫分離可以有效減輕寫庫的壓力,又可以把查詢資料的請求分發到不同讀庫; 2、寫資料庫:當呼叫insert、update、d

(2.1.27.11)Java併發程式設計:Lock之ReentrantReadWriteLock 分離獨享式重入鎖

我們在介紹AbstractQueuedSynchronizer的時候介紹過,AQS支援獨佔式同步狀態獲取/釋放、共享式同步狀態獲取/釋放兩種模式,對應的典型應用分別是ReentrantLock和Semaphore AQS還可以混合兩種模式使用,讀寫鎖Reent

mysql主從搭建及java分離demo

下載mysql版本5.6 新增使用者mysql和組myGroup useradd mysql groupadd myGroup usermod -G myGroup mysql 初始化mysql使用者名稱密碼: passwd mysql 解壓

[Java] springboot多資料來源以及分離

springboot 資料來源路由器    --------------------  分割線  ------------------------- 上面是資料來源繫結,繫結之後接下來就是讀寫分離 在讀寫分離中,很明顯就是將事物型sql轉到主庫,將查詢sql轉入從庫 在進行讀

java多執行緒批量讀取檔案(二)--分離

package com.net.thread.future; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileInp

JAVA學習之路---mysql分離

1.mysql讀寫分離,我們需要在資料來源配置檔案中配置多個數據源 2.自定義動態切換資料來源DynamicDataSource,繼承AbstractRoutingDataSource,該類有實現了DataSource介面 然後我們開啟DynamicDataSource繼

Java多執行緒之 ReadWriteLock 分離的多執行緒實現

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

java分離實現

資料庫配置為一個主庫 多個從庫 主庫用於寫操作 從庫只讀操作讀寫分離實現即為配置兩個資料來源,一個用於讀寫 連線主庫 假設為ds_wr,一個用於只讀 連線從庫 假設為ds_r。對資料庫讀操作時,操作ds_r資料來源。對資料來源寫操作時,操作ds_wr資料來源。讀寫分離可以有兩

CopyOnWriteArrayList 分離,弱一致性

為什麼會有CopyOnWriteArrayList?   我們知道ArrayList和LinkedList實現的List都是非執行緒安全的,於是就有了Vector,它是基於ArrayList的執行緒安全集合,但Vector無論是add方法還是get方法都加上了synchronized修飾,當多執行

MySQL Proxy 分離(實戰總結)

mysql proxy;讀寫分離 規劃: 主mysql服務器:192.168.1.21 從mysql服務器: 192.168.1.22 mysql讀寫分離器:192.168.1.23 1、讀寫分離服務器上解壓安裝包,並添加對應用戶,並編輯啟動腳本; # tar xf mysql-proxy-

redis分離,主從復制

req con word redis讀寫分離 分離 bsp onf 服務 master master配置:(主服務 redis.conf)   requirepass masterpassword (配置密碼)   port 6379 (配置端口) slave配置   re

mysql+mysql_proxy實現分離

mysql-_proxymysql讀寫分離需要基於主從架構實現 mysql主從配置:http://hongchen99.blog.51cto.com/12534281/1917137 mysql-proxy:用於實現mysql主從分離,基於主從架構讀寫分離存在的最大問題就是主從同步延遲 安裝my

mysql 主從實戰及分離

logs 啟動 毫秒 class -- systemctl position 讀寫 mas 1. MYSQL主從原理    1) 至少需要2臺數據庫服務器,一主一從,Master開啟bin-log功能用於記錄主庫增加、刪除、修改、更新SQL語句。   2) 異步復