Java concurrency集合之ConcurrentSkipListSet_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
ConcurrentSkipListSet介紹
ConcurrentSkipListSet是線程安全的有序的集合,適用于高并發(fā)的場(chǎng)景。
ConcurrentSkipListSet和TreeSet,它們雖然都是有序的集合。但是,第一,它們的線程安全機(jī)制不同,TreeSet是非線程安全的,而ConcurrentSkipListSet是線程安全的。第二,ConcurrentSkipListSet是通過ConcurrentSkipListMap實(shí)現(xiàn)的,而TreeSet是通過TreeMap實(shí)現(xiàn)的。
ConcurrentSkipListSet原理和數(shù)據(jù)結(jié)構(gòu)
ConcurrentSkipListSet的數(shù)據(jù)結(jié)構(gòu),如下圖所示:
說(shuō)明:
(01) ConcurrentSkipListSet繼承于AbstractSet。因此,它本質(zhì)上是一個(gè)集合。
(02) ConcurrentSkipListSet實(shí)現(xiàn)了NavigableSet接口。因此,ConcurrentSkipListSet是一個(gè)有序的集合。
(03) ConcurrentSkipListSet是通過ConcurrentSkipListMap實(shí)現(xiàn)的。它包含一個(gè)ConcurrentNavigableMap對(duì)象m,而m對(duì)象實(shí)際上是ConcurrentNavigableMap的實(shí)現(xiàn)類ConcurrentSkipListMap的實(shí)例。ConcurrentSkipListMap中的元素是key-value鍵值對(duì);而ConcurrentSkipListSet是集合,它只用到了ConcurrentSkipListMap中的key!
ConcurrentSkipListSet函數(shù)列表
// 構(gòu)造一個(gè)新的空 set,該 set 按照元素的自然順序?qū)ζ溥M(jìn)行排序。 ConcurrentSkipListSet() // 構(gòu)造一個(gè)包含指定 collection 中元素的新 set,這個(gè)新 set 按照元素的自然順序?qū)ζ溥M(jìn)行排序。 ConcurrentSkipListSet(Collection<? extends E> c) // 構(gòu)造一個(gè)新的空 set,該 set 按照指定的比較器對(duì)其元素進(jìn)行排序。 ConcurrentSkipListSet(Comparator<? super E> comparator) // 構(gòu)造一個(gè)新 set,該 set 所包含的元素與指定的有序 set 包含的元素相同,使用的順序也相同。 ConcurrentSkipListSet(SortedSet<E> s) // 如果此 set 中不包含指定元素,則添加指定元素。 boolean add(E e) // 返回此 set 中大于等于給定元素的最小元素;如果不存在這樣的元素,則返回 null。 E ceiling(E e) // 從此 set 中移除所有元素。 void clear() // 返回此 ConcurrentSkipListSet 實(shí)例的淺表副本。 ConcurrentSkipListSet<E> clone() // 返回對(duì)此 set 中的元素進(jìn)行排序的比較器;如果此 set 使用其元素的自然順序,則返回 null。 Comparator<? super E> comparator() // 如果此 set 包含指定的元素,則返回 true。 boolean contains(Object o) // 返回在此 set 的元素上以降序進(jìn)行迭代的迭代器。 Iterator<E> descendingIterator() // 返回此 set 中所包含元素的逆序視圖。 NavigableSet<E> descendingSet() // 比較指定對(duì)象與此 set 的相等性。 boolean equals(Object o) // 返回此 set 中當(dāng)前第一個(gè)(最低)元素。 E first() // 返回此 set 中小于等于給定元素的最大元素;如果不存在這樣的元素,則返回 null。 E floor(E e) // 返回此 set 的部分視圖,其元素嚴(yán)格小于 toElement。 NavigableSet<E> headSet(E toElement) // 返回此 set 的部分視圖,其元素小于(或等于,如果 inclusive 為 true)toElement。 NavigableSet<E> headSet(E toElement, boolean inclusive) // 返回此 set 中嚴(yán)格大于給定元素的最小元素;如果不存在這樣的元素,則返回 null。 E higher(E e) // 如果此 set 不包含任何元素,則返回 true。 boolean isEmpty() // 返回在此 set 的元素上以升序進(jìn)行迭代的迭代器。 Iterator<E> iterator() // 返回此 set 中當(dāng)前最后一個(gè)(最高)元素。 E last() // 返回此 set 中嚴(yán)格小于給定元素的最大元素;如果不存在這樣的元素,則返回 null。 E lower(E e) // 獲取并移除第一個(gè)(最低)元素;如果此 set 為空,則返回 null。 E pollFirst() // 獲取并移除最后一個(gè)(最高)元素;如果此 set 為空,則返回 null。 E pollLast() // 如果此 set 中存在指定的元素,則將其移除。 boolean remove(Object o) // 從此 set 中移除包含在指定 collection 中的所有元素。 boolean removeAll(Collection<?> c) // 返回此 set 中的元素?cái)?shù)目。 int size() // 返回此 set 的部分視圖,其元素范圍從 fromElement 到 toElement。 NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) // 返回此 set 的部分視圖,其元素從 fromElement(包括)到 toElement(不包括)。 NavigableSet<E> subSet(E fromElement, E toElement) // 返回此 set 的部分視圖,其元素大于等于 fromElement。 NavigableSet<E> tailSet(E fromElement) // 返回此 set 的部分視圖,其元素大于(或等于,如果 inclusive 為 true)fromElement。 NavigableSet<E> tailSet(E fromElement, boolean inclusive)
ConcurrentSkipListSet是通過ConcurrentSkipListMap實(shí)現(xiàn)的,它的接口基本上都是通過調(diào)用ConcurrentSkipListMap接口來(lái)實(shí)現(xiàn)的。這里就不再對(duì)它的源碼進(jìn)行分析了。
ConcurrentSkipListSet示例
import java.util.*; import java.util.concurrent.*; /* * ConcurrentSkipListSet是“線程安全”的集合,而TreeSet是非線程安全的。 * * 下面是“多個(gè)線程同時(shí)操作并且遍歷集合set”的示例 * (01) 當(dāng)set是ConcurrentSkipListSet對(duì)象時(shí),程序能正常運(yùn)行。 * (02) 當(dāng)set是TreeSet對(duì)象時(shí),程序會(huì)產(chǎn)生ConcurrentModificationException異常。 * * @author skywang */ public class ConcurrentSkipListSetDemo1 { // TODO: set是TreeSet對(duì)象時(shí),程序會(huì)出錯(cuò)。 //private static Set<String> set = new TreeSet<String>(); private static Set<String> set = new ConcurrentSkipListSet<String>(); public static void main(String[] args) { // 同時(shí)啟動(dòng)兩個(gè)線程對(duì)set進(jìn)行操作! new MyThread("a").start(); new MyThread("b").start(); } private static void printAll() { String value = null; Iterator iter = set.iterator(); while(iter.hasNext()) { value = (String)iter.next(); System.out.print(value+", "); } System.out.println(); } private static class MyThread extends Thread { MyThread(String name) { super(name); } @Override public void run() { int i = 0; while (i++ < 10) { // “線程名” + "序號(hào)" String val = Thread.currentThread().getName() + (i%6); set.add(val); // 通過“Iterator”遍歷set。 printAll(); } } } }
(某一次)運(yùn)行結(jié)果:
a1, b1, a1, a1, a2, b1, b1, a1, a2, a3, b1, a1, a2, a3, a1, a4, b1, b2, a2, a1, a2, a3, a4, a5, b1, b2, a3, a0, a4, a5, a1, b1, a2, b2, a3, a0, a4, a1, a5, a2, b1, a3, b2, a4, b3, a5, a0, b1, a1, b2, a2, b3, a3, a0, a4, a1, a5, a2, b1, a3, b2, a4, b3, a5, b4, b1, a0, b2, a1, b3, a2, b4, a3, a0, a4, a1, a5, a2, b1, a3, b2, a4, b3, a5, b4, b1, b5, b2, a0, a1, a2, a3, a4, a5, b3, b1, b4, b2, b5, b3, a0, b4, a1, b5, a2, a0, a3, a1, a4, a2, a5, a3, b0, a4, b1, a5, b2, b0, b3, b1, b4, b2, b5, b3, b4, a0, b5, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5, a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5, a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5, a0, a1, a2, a3, a4, a5, b0, b1, b2, b3, b4, b5,
結(jié)果說(shuō)明:
示例程序中,啟動(dòng)兩個(gè)線程(線程a和線程b)分別對(duì)ConcurrentSkipListSet進(jìn)行操作。以線程a而言,它會(huì)先獲取“線程名”+“序號(hào)”,然后將該字符串添加到ConcurrentSkipListSet集合中;接著,遍歷并輸出集合中的全部元素。 線程b的操作和線程a一樣,只不過線程b的名字和線程a的名字不同。
當(dāng)set是ConcurrentSkipListSet對(duì)象時(shí),程序能正常運(yùn)行。如果將set改為TreeSet時(shí),程序會(huì)產(chǎn)生ConcurrentModificationException異常。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringCloud客戶端的負(fù)載均衡Ribbon的實(shí)現(xiàn)
微服務(wù)架構(gòu),不可避免的存在單個(gè)微服務(wù)有多個(gè)實(shí)例,這篇文章主要介紹了SpringCloud客戶端的負(fù)載均衡Ribbon的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2018-06-06解決maven常見錯(cuò)誤:Dependency is duplicated in
這篇文章主要介紹了解決maven常見錯(cuò)誤:Dependency is duplicated in file(s):問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04Netty啟動(dòng)流程注冊(cè)多路復(fù)用源碼解析
這篇文章主要介紹了Netty啟動(dòng)流程注冊(cè)多路復(fù)用源碼分析,繼續(xù)分析channel是如何注冊(cè)到selector中的,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-03-03MybatisPlus的LambdaQueryWrapper用法詳解
LambdaQueryWrapper<Tag>?是 MyBatis-Plus 框架中的一個(gè)功能強(qiáng)大的查詢構(gòu)造器,它用于構(gòu)建 SQL 查詢條件,具有一定的參考價(jià)值,感興趣的可以了解一下2024-10-10Springboot實(shí)現(xiàn)XSS漏洞過濾的示例代碼
這篇文章主要介紹了Springboot實(shí)現(xiàn)XSS漏洞過濾的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Spring @Profile注解實(shí)現(xiàn)多環(huán)境配置
這篇文章主要介紹了Spring @Profile注解實(shí)現(xiàn)多環(huán)境配置,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04