ArrayList 線程安全性學習

引言

最近學校的氛圍比較活躍,考研的複習,不考研的都在寫簡歷準備面試。前端

看了看,最近也沒有好公司來辦宣講會,也就沒了投簡歷的意向。最近看了看面試題,想着補一補基礎,之後面幾家Spring Cloud的企業,去和麪試官交流交流。java

Spring Cloud的學習與體會面試

最近看了《Spring Cloud微服務實戰》一書,感受受益不淺,大有裨益。數據庫

高併發應用,必須是要啓用Spring Cloud的。有了Spring Cloud,就不用再像以前同樣,前端工程師團隊,後端工程師團隊,運維團隊。而是按模塊劃分,訂單模塊團隊,支付模塊團隊,每一個團隊裏都是從前端到後臺到運維的全棧工程師。後端

就像上次黃庭祥說的,ThinkPHP開發,他寫學期管理;AngularJS開發,他又寫學期管理;Angular開發,他還寫學期管理。想到什麼了麼?確定精通這個模塊的業務邏輯啊?數組

若是培養出優秀的支付模塊團隊、優秀的安全模塊團隊、優秀的高併發優化團隊,其實淘寶也不過如此。安全

相互的依賴,從原來的@Autowired轉爲服務器接口間的調用。每一個模塊都是一個Spring Cloud應用,各應用間經過互相調用、相互協做共同實現業務功能,同時,各應用模塊能夠採用不一樣的數據庫,以發揮各數據庫之所長。服務器

而後後臺分佈式部署,到了併發的時候,給相應的模塊加服務器負載均衡就是了。我的中心模塊,不經常使用,兩個服務器負載;訂單模塊,可能會併發,加個百十來個服務器負載均衡。固然,像618、雙十一這樣的場景,確定不是加服務器就能解決的,我這裏只是舉個簡單的例子。模塊劃分以後,能夠有針對性地解決高併發問題。前端工程師

不扯淡了,開始進入正題。多線程

面試題

再談線程安全

什麼是線程安全?

我看到這道題就感受怎麼也說不出來,就是多線程的環境下運行,我這個應用也不炸,雖然是這個意思,可是也不能這樣回答啊?一時之間,找不到相關的學術詞彙回答此問題。

這是想了許久後,我本身總結出的回答:

程序在單線程環境下正常執行獲得了正確的結果,在多個線程併發執行的環境條件下,仍然能獲得像單線程同樣正確的結果,這就是線程安全。

若是一個類(或對象),咱們在使用時,無需考慮任何多線程相關的問題,就像單線程同樣使用,且最後能獲得正確的結果,那就說這個類(或對象)是線程安全的。

ArrayList線程安全嗎?

看了許多面試題,發現面試官都喜歡以一個小方面進行切入,而後無限擴展,直到把面試者問懵圈爲止。

ArrayList線程安全嗎?

雖然每天用ArrayList,可是真的沒考慮過這個問題。其實,ArrayList線程不安全。

ArrayList是一個內部採用數組實現的線性表,它相比數組最大的優勢就是使用時能夠不用去像數組同樣new的時候去考慮要容納多少個元素。ArrayList默認構造一個容量爲10的數組。

private static final int DEFAULT_CAPACITY = 10;

若是容量不夠了,ArrayList會自動擴容,擴容至原來的1.5倍。(右移一位,至關於除以2)。

int newCapacity = oldCapacity + (oldCapacity >> 1);

ArrayList沒有對多線程問題進行處理,舉個add方法的例子就能證實它線程不安全。

elementData[size++] = e;

別看這是一行,實際上是執行了兩步操做,賦值和自增。

線程A add一個元素,而後暫停執行,size還沒自增,而後線程Badd元素,size沒變,就直接把A add的元素覆蓋了。

不安全爲何要使用?

又回到了以前向晨澍請教的問題,線程安全,必然是有額外開銷的。

因此List的三個接口ArrayListLinkedListVector

線程不安全的要比線程安全的執行效率高。因此咱們經常使用的是線程不安全的ArrayListLinkedList,而歷來沒有用過線程安全的Vector

VectorJDK1.0就存在,設計得不夠完善,多線程狀況下若是使用不當也會發生錯誤,不推薦使用。

如何解決線程不安全

既然Vector不能用,那我就想要一個線程安全的List得怎麼整呢?

調用Collections.synchronizedList方法,使ArrayList線程安全。

List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());

返回SynchronizedList類的對象,經典的裝飾器模式,對方法訪問加了同步。

public void add(int index, E element) {
    synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
    synchronized (mutex) {return list.remove(index);}
}

總結

何處望神州?滿眼風光北固樓。千古興亡多少事?悠悠。不盡長江滾滾流。

年少萬兜鍪,坐斷東南戰未休。天下英雄誰敵手?曹劉。生子當如孫仲謀。

——辛棄疾 《南鄉子·登京口北固亭有懷》

相關文章
相關標籤/搜索