java學習|圖說多線程(一)那些孿生的線程(不)安全的類

本文爲多線程第一篇,java

不深刻細節,數據庫

大致上聊一聊咱們經常使用的類,安全

先來一張圖感覺下:多線程

java學習|圖說多線程(一)那些孿生的線程(不)安全的類

在上面三組類中,開發時咱們大都是使用的上面的,如使用StringBuilder作String拼接。 使用ArrayList存儲數據庫返回的一組數據, 用HashMap傳參等等。app


由於如今開發大都是在SpringMVC下開發,全局變量都是一些Manager, Service,Mapper之類的。 而後咱們的List, Map變量通常都是在方法裏面新建,使用,返回。在jvm中,局部變量存在於vm棧的每一個方法的棧幀中,這個線程所私有的,不會引起線程安全問題,因此咱們用上面的或是下面的程度大均可以正確的運行,也正是這樣,也讓咱們一直沒有機會深刻到他們之中,看看他們有什麼不同jvm


StringBuilder VS StringBuffer , 對比方法 append()ide

java學習|圖說多線程(一)那些孿生的線程(不)安全的類

ArrayList VS Vector , 對比方法 add()學習

java學習|圖說多線程(一)那些孿生的線程(不)安全的類

HashMap VS Hashtable , 對比方法 put() ui

java學習|圖說多線程(一)那些孿生的線程(不)安全的類

細心的小夥伴們估計已經注意到了,線程

兩個類的這些方法中,

方法名,參數,返回值,

和實現都大致上差很少,

只是在方法聲明上有些差異:

synchronized.synchronized放在非static方法是,

是對當前實例加鎖,

例:

Hashtable<String,String> table = new Hashtable<>();

table.put("java","技術大本營");

table.get("java");
java學習|圖說多線程(一)那些孿生的線程(不)安全的類

咱們在使用table 這個實例時,線程A要使用table的get方法,就要先等別的線程使用完put方法。這種讀寫相間的說是爲了保證數據一致加個鎖倒也無可厚非,可是,若是兩個線程都是使用get方法,也是同一時間只有一個線程能讀取。因此如今在項目中不多看到後Vector 和 hashtable出現了。

從平常開發中,咱們不難總結出,讀 實際上是不須要加鎖的,只有寫的時候才須要加鎖,並且寫的時候也不至於從方法第一行就加鎖,能夠只對更改的那幾行加鎖就能夠了,或者對數據分段,對須要修改的那一段數據加鎖。 總體的思路就是,下降鎖的粒度。 還有更厲害的就是直接不加鎖了,你們一塊兒去競爭,但改以前必需要和本身之前拿到的數據對比,中間沒有人動過才能改。

相信已經有小夥伴經過上段的描述想到了對應的例子,如ConcurrentHashMap , CAS等等 , 這些是後話,今天先和你們一塊兒認識一些孿生的線程(不)安全的類。


總結:一般一提到線程安全,你們都會第一時間想到加鎖,但對誰加鎖,何時加鎖,是個值得考量的問題!

相關文章
相關標籤/搜索