面試官:Java 有線程安全的 set 嗎?我竟然答不上來..

2021-12-29 Java基基

點擊上方「Java基基」,選擇「設為星標」

做積極的人,而不是積極廢人!

每天 14:00 更新文章,每天掉億點點頭髮...

來源:blog.csdn.net/li_canhui/
article/details/91393247

在多線程環境下,要使用線程安全的集合,比如,ConcurrentHashMap是線程安全的HashMap,CopyOnWriteArrayList是線程安全的ArrayList。

那麼HashSet對應的線程安全集合,是什麼呢?java有沒有提供默認實現呢?

在java的concurrent包中,我找到了CopyOnWriteArraySet,那麼它是線程安全的嗎?下面是測試代碼。

public static void main(String[] args) {
    Set<String> 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());
}

經過多次執行,結果都是10000。可以說明,CopyOnWriteArraySet是線程安全的Set。

那麼CopyOnWriteArraySet是如何保證寫入時的線程安全呢?以下是CopyOnWriteArraySet的add源碼。

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 < fence; i++)
            if (elements[i] == null)
                return i;
    } else {
        for (int i = index; i < fence; 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 < 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();
    }
}

從源碼可以看出,CopyOnWriteArraySet底層採用了CopyOnWriteArrayList數據結構來實現。在add元素時,採用的是可重入鎖來實現線程安全。

歡迎加入我的知識星球,一起探討架構,交流源碼。加入方式,長按下方二維碼噢

已在知識星球更新源碼解析如下:

最近更新《芋道 SpringBoot 2.X 入門》系列,已經 101 餘篇,覆蓋了 MyBatis、Redis、MongoDB、ES、分庫分表、讀寫分離、SpringMVC、Webflux、權限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能測試等等內容。

提供近 3W 行代碼的 SpringBoot 示例,以及超 6W 行代碼的電商微服務項目。

獲取方式:點「在看」,關注公眾號並回復 666 領取,更多內容陸續奉上。

文章有幫助的話,在看,轉發吧。

謝謝支持喲 (*^__^*)

相關焦點

  • 面試官:你工作3年了,ArrayList是線程不安全都沒掌握,不應該啊
    作為一名java程式設計師,對ArrayList,相信再熟悉不過了。這個類我們平時接觸得最多的一個列表集合類。面試時,也有不少面試官會針對此知識點考察求職者。小愛最近又去面試了,最近到某知名網際網路公司面試,做了筆試題後,面試官剛好問ArrayList是線程安全還是非線程安全?小愛說是非線程安全,面試官問,你能說說為什麼是非線程安全嗎?小愛一時間說不出個所以然。
  • JAVA面試題及答案一百道(SE篇上)——老面試官的經驗之談
    上篇請看這裡-->JAVA面試題及答案一百道(SE篇上)——老面試官的經驗之談本文的面試題裡有部分關於設計模式的題目,但是阿偉要在這裡提醒各位一句話,找工作時面試官的水平可以清晰地反映出這個公司的水平,如果你的面試官抓住設計模式死摳死問,想讓你一成不變的把網上的面試答案背下來
  • 因為不知道Java的CopyOnWriteArrayList,面試官讓我回去等通知
    hello,同學們,大家好,我是沉默王二,在我為數不多的面試經歷中,有一位姓馬的面試官令我印象深刻,九年過去了,我還能記得他為數不多的發量。老馬:「兄弟,ArrayList 是線程安全的嗎?」王二:「不是啊。」老馬:「那有沒有線程安全的 List?」王二:「有啊,Vector。」老馬:「還有別的嗎?」
  • 面試官:Java 反射是什麼?我回答不上來!
    反射是java語言的一個特性,它允程序在運行時(注意不是編譯的時候)來進行自我檢查並且對內部的成員進行操作。例如它允許一個java的類獲取他所有的成員變量和方法並且顯示出來。Java 的這一能力在實際應用中也許用得不是很多,但是在其它的程序設計語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數定義相關的信息。
  • Java開發面試故事,你能學習到很多經驗
    為了考察L君的編程水平,筆者先給L君上了一道正餐前的開胃菜,出了一個比較簡單的題目:程序開發時為什麼要用多線程,單線程不是很好嗎?多線程有什麼意義?多線程會帶來哪些問題,如何解決?以上問題對於一個合格的Java工程師來說是非常簡單的。出人意料的是,這位有著6年以上開發經驗的L君竟然沒有答上來。L君的理由是這個問題太理論、太基礎,已經忘記其答案了。
  • 面試官:Java 反射是什麼?我竟回答不上來!
    反射是java語言的一個特性,它允程序在運行時(注意不是編譯的時候)來進行自我檢查並且對內部的成員進行操作。例如它允許一個java的類獲取他所有的成員變量和方法並且顯示出來。Java 的這一能力在實際應用中也許用得不是很多,但是在其它的程序設計語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數定義相關的信息。
  • 面試官提問回答不上來怎麼辦?
    面試官提問回答不上來怎麼辦?面試是每個求職者在求職過程中都會經歷的一步,也是最重要的一步。面試尷尬,如何從容應對?
  • 面試官:Java 8 map 和 flatMap 的區別?大部分人答不上來!
    來源丨經授權轉自 Java技術棧(ID:javastack)背景棧長面試會經常問 Java 8 map 和 flatMap 的區別,大部分人都答不上來,會用 map 的都不多,還有一部分人甚至都不知道這兩個玩意是幹嘛用的,有的還以為我問 HashMap 和 FlatMap。。
  • 簡單的面試題目,大跌眼鏡的結果(JAVA)
    招聘高峰這種情況尤甚,浪費你我時間。所以越來越多的組織會採用電話面試的方式,進行初步篩選。題目難度一再降低,結果卻大跌眼鏡,HR都哭了。以下是一個簡單統計,樣本幾百人不等,能夠全部答上來的,不超過10%。哦,全錯的也有!快來看看我這b裝的分數高,還是你得的分數高,滿分10分!
  • Java面試變成八股文? 我終於知道了真相...
    所以大多數北美工程師的面試準備是這樣的:我見過刷300題左右進Google的,也見過刷1000+題還拿不到offer的.但總的來說,只要面試中遇到的算法題,能夠按自己的思路做出來,並能應對面試官的follow up,這一關基本就妥了。所以大多數人會在跳槽前刷LintCode這類的在線編程測評題庫。
  • 2017年網友京東Java面試經驗:感覺問的比較基礎,大家都是這樣?
    面試官比較好,說你不能來也很正常,我們來進行一個20分鐘的面試吧。0.HTTP TCP UDP 的區別,具體用在哪些場景。1.說一下 java中的隊列 set map 區別,java裡的數據結構。講講它們的實現。
  • 面試總結——Java高級工程師
    一、獨白之前也面試別人,現在輪到自己找工作,怎麼說呢,每個面試官的看法不一樣,面試的方式就不一樣,比如我面試別人我喜歡問項目中他用到了那些,然後針對用到的技術去問一些問題,或者說對於某些場景的一些技術實現方案是我特別喜歡問的,比如當你的接口服務數據被人截包了,你如何防止數據惡意提交?
  • 面試官:口字加一撇,組成什麼字?小夥兒:我能答三個
    小夥兒:我能答三個職場面試是能否順利就業的敲門磚,很多面試者與自己心儀的工作錯之交臂,都會抱怨是被面試官在面試過程中出的奇葩問題給「刁難」了,其實面試官並非無理取鬧之輩,他們問這些問題,反而是為了更好的篩選出崗位最適合的人才,而特定的問題。感覺到難,答不出來,只能說明你不適合這個崗位。
  • 面試官:「山」字減去一筆,是個什麼字?北大生答不上來,你行嗎
    面試官:「山」字減去一筆,是個什麼字?北大生答不上來,你行嗎最近面試官們喜歡在面試求職者的時候出一些字謎之類的題,把很多的求職者都給搞蒙了,能答出問題的寥寥無幾,除非你的應變能力特別的強,北大生求職者黃渤在面試之前就準備了很多相關的材料,但是在面試結尾的時候,面試官依然出了一道「字謎」題目,讓北大生好生不解,題目是這樣的:面試官:「山」字減去一筆,是個什麼字?北大生答不上來,你行嗎?
  • 複試答不上來怎麼辦?四個妙招搞定面試!
    你現在了解目標學校的複試流程了嗎?好吧,不了解也沒關係雖然每個學校每個專業的複試都不太一樣,但籠統的可以將複試分為兩項:「筆試+面試」,其中面試又包括「英語口語面試」和「專業課面試」。筆試對大家不算陌生,至於面試,很多人就很虛了。從小到大的面試經歷可能屈指可數。
  • 我和面試官的博弈:Java 並發編程篇
    面試官:給你看下面一段代碼,你說下會存在加鎖的操作嗎?面試官:你能說下輕量級鎖嗎?我:輕量級鎖提升程序同步性能的依據是:對於絕大部分的鎖,在整個同步周期內是不存在競爭的(區別於偏向鎖),這是一個經驗數據。
  • 被虐的有點慘的有贊Java面試解析
    我的有贊面經,如果對面經感興趣,可以在公眾號裡面回復"面經"即可以看到更多我以前寫的。昨天的一面面試解析:Java 面試解析(有贊一面)以下是朋友的文章,請閱讀。記住,基礎再好,也架不住面試官天馬行空的問,所以刷面試題還是很有必要的!本文不適合人群:專攻JAVA某方面技術的人因為這類人專攻JAVA某塊技術,知識容易出現死角。貿然閱讀本文,發現自己一堆題目都不會,會覺得有一種挫敗感,發現自己連校招生都不如。
  • JAVA面試解析(有贊二面)
    因此,如果是為了面試,完全是有套路可以準備的!記住,基礎再好,也架不住面試官天馬行空的問,所以刷面試題還是很有必要的!本文不適合人群:專攻JAVA某方面技術的人因為這類人專攻JAVA某塊技術,知識容易出現死角。貿然閱讀本文,發現自己一堆題目都不會,會覺得有一種挫敗感,發現自己連校招生都不如。
  • 2020年Java面試整理最全:29核心知識+350家面試真題+面試神技
    (後來面試官說了使用top命令)計算機網絡9.tcp和udp的區別答:tcp是面向連接的,udp不面向連接;tcp是一對一的,udp可以是一對一、一對多、多對一和多對多;tcp面向字節流提供服務,udp面向報文提供服務;tcp是安全的,udp不安全
  • Java面試總結之Java基礎
    無論是工作多年的高級開發人員還是剛入職場的新人,在換工作面試的過程中,Java基礎是必不可少的面試題之一。能不能順利通過面試,拿到自己理想的offer,在準備面試的過程中,Java基礎也是很關鍵的。對於工作多年的開發人員來說,Java基礎往往是會被大家所忽略的,但在面試的過程中,確是必不可少的問題。在這篇文章裡就來為大家總結一下經常會被問到的Java基礎題。