面試官:Java 有線程安全的 set 嗎?我竟然答不上來。
=?0???false?:????????addIfAbsent(e,?snapshot);}private?static?int?indexOf(Object?o,?Object[]?elements,???????????????????????????int?index,?int?fence)?{????if?(o?==?null)?{????????for?(int?i?=?index;?i?=?0)????????????????????return?false;????????}????????Object[]?newElements?=?Arrays.copyOf(current,?len?+?1);????????newElements[len]?=?e;????????setArray(newElements);????????return?true;????}?finally?{????????lock.unlock();????}}從源碼可以看出,CopyOnWriteArraySet底層采用了CopyOnWriteArrayList數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)。在add元素時,采用的是可重入鎖來實現(xiàn)線程安全。" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" wah-hotarea="click" style="outline: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"> public?static?void?main(String[]?args)?{
????Set?set?=?new?CopyOnWriteArraySet<>();
????ExecutorService?service?=?Executors.newFixedThreadPool(12);
????int?times?=?10000;
????AtomicInteger?flag?=?new?AtomicInteger(0);
????for(int?i?=?0;?i?times;?i?++){
????????service.execute(()->{
????????????set.add("a"?+?flag.getAndAdd(1));
????????});
????}
????service.shutdown();
????try?{
????????service.awaitTermination(Long.MAX_VALUE,?TimeUnit.DAYS);
????}catch?(Exception?e){
????????e.printStackTrace();
????}
????System.out.println(set.size());
}
=?0???false?:????????addIfAbsent(e,?snapshot);}private?static?int?indexOf(Object?o,?Object[]?elements,???????????????????????????int?index,?int?fence)?{????if?(o?==?null)?{????????for?(int?i?=?index;?i?=?0)????????????????????return?false;????????}????????Object[]?newElements?=?Arrays.copyOf(current,?len?+?1);????????newElements[len]?=?e;????????setArray(newElements);????????return?true;????}?finally?{????????lock.unlock();????}}從源碼可以看出,CopyOnWriteArraySet底層采用了CopyOnWriteArrayList數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)。在add元素時,采用的是可重入鎖來實現(xiàn)線程安全。" data-itemshowtype="0" tab="innerlink" data-linktype="2" wah-hotarea="click" hasload="1" style="outline: 0px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer;"> public?boolean?add(E?e)?{
????return?al.addIfAbsent(e);
}
public?boolean?addIfAbsent(E?e)?{
????Object[]?snapshot?=?getArray();
????return?indexOf(e,?snapshot,?0,?snapshot.length)?>=?0???false?:
????????addIfAbsent(e,?snapshot);
}
private?static?int?indexOf(Object?o,?Object[]?elements,
???????????????????????????int?index,?int?fence)?{
????if?(o?==?null)?{
????????for?(int?i?=?index;?i?????????????if?(elements[i]?==?null)
????????????????return?i;
????}?else?{
????????for?(int?i?=?index;?i?????????????if?(o.equals(elements[i]))
????????????????return?i;
????}
????return?-1;
}
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?????????????????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();
????}
}
END
推薦閱讀 一鍵生成Springboot & Vue項目!【畢設(shè)神器】
Java可視化編程工具系列(一)
Java可視化編程工具系列(二)
順便給大家推薦一個GitHub項目,這個 GitHub 整理了上千本常用技術(shù)PDF,絕大部分核心的技術(shù)書籍都可以在這里找到,
GitHub地址:https://github.com/javadevbooks/books
Gitee地址:https://gitee.com/javadevbooks/books
電子書已經(jīng)更新好了,你們需要的可以自行下載了,記得點一個star,持續(xù)更新中..
評論
圖片
表情

