国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類

這篇具有很好參考價值的文章主要介紹了javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java

T04BF

??專欄: 算法|JAVA|MySQL|C語言

?? 小比特 大夢想

此篇文章與大家分享多線程專題的最后一篇文章:關于JUC常見的類以及線程安全的集合類
如果有不足的或者錯誤的請您指出!

3.JUC(java.util.concurrent)常見的類

3.1Callable接口

Callable和Runnable一樣,都是用來描述一個任務的
但是區(qū)別在于 ,用Callable描述的任務是有返回值的,而通過Runnable描述的任務是沒有返回值的(即run方法的返回值是void)
通過Runnable,要想獲取到"返回值",只能通過一些特定的手段
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java
但是這個方法,主線程和 t線程的耦合太大了
而Callable就是為了會更優(yōu)雅的解決上面的問題
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java
但是Thread并沒有提供這樣的構造方法
我們可以將callable傳入FutureTask
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java

3.2 RentrantLock

表示可重入的鎖
相對于我們常用的Synchronized,ReentrantLock是"手動"進行加鎖和解鎖的

    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        //加鎖
        lock.lock();
        //解鎖
        lock.unlock();
    }

但是這種就容易"漏掉"解鎖操作,就會出現(xiàn)大問題,因此我們經常搭配finally使用
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java
既然這個這么麻煩,那還有存在的價值嘛??
實際上價值還是很大的

ReentrantLock提供了公平鎖的實現(xiàn)

javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java
如果傳入true就是表示公平鎖,傳入false / 不傳 就是非公平鎖

ReentrantLock提供了tryLock

所謂tryLock就是嘗試加鎖
如果在遇到鎖已經被占有了,那就直接返回
而相比于synchronized則是阻塞等待
另外,除了直接返回外,tryLock還提供了帶等待超時的版本

Condition

Synchronized是搭配 wait 和 notify使用
而ReentrantLock是搭配Condition使用
實際上Condition比wait和notify更加智能,因為它可以指定喚醒那個線程

3.3 Semaphore

表示信號量,用來表示"可用資源"的個數(shù),本質上就是個計數(shù)器
圍繞信號量主要有兩個基本操作
(1)P操作,即申請資源,計數(shù)器 -1;
(2)V操作,即釋放資源,計數(shù)器+1;
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java
但我們申請的資源超過信號量本身的大小們,就會阻塞等待,直到其他地方釋放資源
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java
那么當資源數(shù)目為1的話,就可以當成鎖來使用了
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java

因為如果信號量有0 1兩個取值,此時就是"二元信號量",本質上就是一把鎖

3.4CountDownLatch

表示同時等待多個線程結束
是一個比較實用的工具
當我們把一個任務拆解成多個線程來完成時,就可以利用這個工具類來判斷,任務整體是否完成了
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java
此時的執(zhí)行結果就是:
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java
await會阻塞等待,一直到countDown調用的次數(shù),和構造方法指定的次數(shù)一致的時候,await才會返回

而await不僅僅能夠替代join,假設現(xiàn)在有1000個任務要交給4個線程來使用,那么如何判斷1000個任務已經執(zhí)行結束??就可以使用countDownLatch來判斷

4.線程安全的集合類

原來的集合類.比如ArrayList,LinkedList,HashMap等等,都是線程不安全的
而Vector自帶了synchronized,Stack繼承了ector,HashTable也是自帶的synchronized,在一定程度上是線程安全的

但是不能說太絕對,還是要具體情況具體分析 就比如可能出現(xiàn)下面這種情況:
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java
就比如上述代碼,線程1執(zhí)行到if條件判斷后,線程2把vector給清空了,就會出現(xiàn)bug

如果需要用到其他的類,就需要手動加鎖,來保證線程安全,但不同情況下加鎖的情況是不一樣的,手動加鎖是比較麻煩的

標準庫就提供了一些具體的解決方法

4.1多線程環(huán)境下使用ArrayList

4.1.1Collection.synchronizedList(new ArrayList)

這種方法就相當于給這些集合類套了一層殼,殼上對集合類里面的一些關鍵方法加上了鎖,起到了類似Vector的效果

4.1.2CopyOnWriteArrayList

利用的是"寫時拷貝"的思想
假設我們現(xiàn)在有一組數(shù)據(jù)為1 2 3 4,此時某個線程對數(shù)據(jù)進行了修改,就把2 修改成200,3修改成300,但是在修改的時候有別到線程在讀,如果直接修改就有可能出現(xiàn)2,300這樣的中間數(shù)據(jù)
而寫時拷貝就是將原來的數(shù)據(jù)集拷貝一份,這樣修改的時候是在新拷貝的數(shù)據(jù)集上修改的,而讀的時候是在舊的數(shù)據(jù)集上讀的
等到修改完后,就用新的數(shù)據(jù)集的引用代替原來舊的數(shù)據(jù)集的引用
這樣的過程中,不會出現(xiàn)任何加鎖和阻塞等待,也保證讀數(shù)據(jù)不會出現(xiàn)"錯誤的數(shù)據(jù)"

這種操作實際上實用性非常高,就比如有的服務器需要更新配置文件 / 數(shù)據(jù)文件,就可以采取上述策略

4.2多線程使用隊列

直接使用BlockingQueue即可

4.3多線程使用哈希表

HashMap是線程不安全的,而HashTable是帶鎖的
但是實際上HashTable并不推薦使用
因為HashTable本質上就是簡單粗暴將每一個方法都進行加鎖,就相當于針對了this加鎖,此時只要針對HashTable上的元素進行操作,就都會涉及到鎖
推薦使用的是 ConcurrentHashTable
它的優(yōu)點就在于:
(1)采用鎖桶的方式,來代替之前的"全局一把鎖"
javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java
此時如果兩個線程針對的是不同鏈表上的元素進行操作,是不會涉及到鎖沖突的
而本身,操作兩個鏈表上的元素,不涉及公共變量,是不會有線程安全問題的
進行這樣的操作實際上收益是很多的
因為在一個Hash表里面,桶的數(shù)量是很多的,此時按照我們上面的操作進行加鎖,大部分情況是可以避免鎖沖突的

那么好像鎖多了,鎖對象就多了是不是更加麻煩了??
實際上,由于java中任何的對象都可以作為鎖對象,我們只需將每一個鏈表的頭結點作為鎖對象即可

(2)引入CAS機制
實際上即使是上面的操作,也不能保證線程安全
像哈希表的size,即使你插入的是不同鏈表的元素,修改的時候也會涉及到多線程修改同一個變量
此時引入了CAS機制,通過CAS來修改size,也就不涉及加鎖操作了

(3)針對擴容進行了特殊優(yōu)化

在哈希表中,如果發(fā)現(xiàn)負載因子太大了,就需要擴容,而擴容是一比較低效的操作,普通的hash表如果要在一次put完成整個擴容操作,就會使得put非常卡,如果平時使用put假設是1ms,但某次put執(zhí)行了1000ms,就會造成不好的體驗

ConcurrentHashMap進行的實際上是"化整為零",在擴容的時候會搞兩份空間

一份是擴容前的空間,一份是擴容后的空間

接下載每次進行哈希表的基本操作的時候,都會將一部分數(shù)據(jù)從舊空間搬到新空間

不是一口氣搬完,分多次搬

搬的過程中,

如果進行的是插入操作,那就插到新的空間里面

如果是刪除,那么舊的新的都會刪除

如果是查找,那么舊的新的都要查找一遍

就是"重哈希"過程,重哈希過程結束的標志通常是所有元素都被成功地移動到了新的空間中,并且舊空間中不再包含任何元素。

感謝您的訪問!!期待您的關注!!!

javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類,Java,java-ee,java文章來源地址http://www.zghlxwxcb.cn/news/detail-857309.html

T04BF

?? 小比特 大夢想

到了這里,關于javaEE初階——多線程(九)——JUC常見的類以及線程安全的集合類的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【JavaEE初階】 線程安全

    【JavaEE初階】 線程安全

    線程安全是多線程編程是的計算機程序代碼中的一個概念。在擁有共享數(shù)據(jù)的多條線程并行執(zhí)行的程序中,線程安全的代碼會通過同步機制保證各個線程都可以正常且準確的執(zhí)行,不會出現(xiàn)數(shù)據(jù)污染等意外情況。上述是百度百科給出的一個概念解釋。換言之,線程安全就是某

    2024年02月08日
    瀏覽(24)
  • JavaEE 初階篇-深入了解進程與線程(常見的面試題:進程與線程的區(qū)別)

    JavaEE 初階篇-深入了解進程與線程(常見的面試題:進程與線程的區(qū)別)

    ??博客主頁:?【 小扳_-CSDN博客】 ?感謝大家點贊??收藏?評論? 文章目錄 ? ? ? ? 1.0 進程概述 ? ? ? ? 2.0 線程概述 ? ? ? ? 2.1 多線程概述 ? ? ? ? 3.0 常見的面試題:談談進程與線程的區(qū)別 ? ? ? ? 4.0 Java 實現(xiàn)多線程的常見方法 ? ? ? ? 4.1 實現(xiàn)多線程方法 - 繼承

    2024年04月13日
    瀏覽(33)
  • 【JavaEE初階】多線程進階(五)常見鎖策略 CAS synchronized優(yōu)化原理

    【JavaEE初階】多線程進階(五)常見鎖策略 CAS synchronized優(yōu)化原理

    樂觀鎖:預測鎖競爭不是很激烈。 悲觀鎖:預測鎖競爭會很激烈。 以上定義并不是絕對的,具體看預測鎖競爭激烈程度的結論。 輕量級鎖加鎖解鎖開銷比較小,效率更高。 重量級鎖加鎖解鎖開銷比較大,效率更低。 多數(shù)情況下,樂觀鎖也是一個輕量級鎖。 多數(shù)情況下,悲

    2024年02月03日
    瀏覽(31)
  • 【JavaEE】線程安全的集合類

    【JavaEE】線程安全的集合類

    作者主頁:paper jie_博客 本文作者:大家好,我是paper jie,感謝你閱讀本文,歡迎一建三連哦。 本文于《JavaEE》專欄,本專欄是針對于大學生,編程小白精心打造的。筆者用重金(時間和精力)打造,將基礎知識一網打盡,希望可以幫到讀者們哦。 其他專欄:《MySQL》《C語言》

    2024年01月20日
    瀏覽(28)
  • Java - JUC(java.util.concurrent)包詳解,其下的鎖、安全集合類、線程池相關、線程創(chuàng)建相關和線程輔助類、阻塞隊列

    Java - JUC(java.util.concurrent)包詳解,其下的鎖、安全集合類、線程池相關、線程創(chuàng)建相關和線程輔助類、阻塞隊列

    JUC是java.util.concurrent包的簡稱,在Java5.0添加,目的就是為了更好的支持高并發(fā)任務。讓開發(fā)者進行多線程編程時減少競爭條件和死鎖的問題 java.lang.Thread.State tools(工具類):又叫信號量三組工具類,包含有 CountDownLatch(閉鎖) 是一個同步輔助類,在完成一組正在其他線程中

    2024年02月05日
    瀏覽(22)
  • 【多線程初階】Thread類常見方法以及線程的狀態(tài)

    【多線程初階】Thread類常見方法以及線程的狀態(tài)

    本文是屬于多線程初階內容系列的, 如果還沒有學習過之前文章的, 請先移步博主的之前的文章進行學習, 本文就是在學會線程的創(chuàng)建后, 再帶大家認識一下 Thread 類以及其常見的方法, 再給大家講解一下線程都有哪些狀態(tài). 關注收藏, 開始學習吧?? 通過我們上篇文章的學習, 我

    2024年02月16日
    瀏覽(27)
  • JavaEE 初階篇-深入了解多線程安全問題(指令重排序、解決內存可見性與等待通知機制)

    JavaEE 初階篇-深入了解多線程安全問題(指令重排序、解決內存可見性與等待通知機制)

    ??博客主頁:?【 小扳_-CSDN博客】 ?感謝大家點贊??收藏?評論? 文章目錄 ? ? ? ? 1.0 指令重排序概述 ? ? ? ? 1.1 指令重排序主要分為兩種類型 ? ? ? ? 1.2 指令重排序所引發(fā)的問題 ? ? ? ? 2.0 內存可見性概述 ? ? ? ? 2.1 導致內存可見性問題主要涉及兩個方面 ? ? ?

    2024年04月15日
    瀏覽(23)
  • 【Java|多線程與高并發(fā)】JUC中常用的類和接口

    【Java|多線程與高并發(fā)】JUC中常用的類和接口

    JUC是Java并發(fā)編程中的一個重要模塊,全稱為 Java Util Concurrent (Java并發(fā)工具包),它提供了一組用于多線程編程的工具類和框架,幫助開發(fā)者更方便地編寫線程安全的并發(fā)代碼。 本文主要介紹 Java Util Concurrent 下的一些常用接口和類 Callable接口類似于Runnable. 有一點區(qū)別就是

    2024年02月12日
    瀏覽(20)
  • java基礎之線程安全問題以及線程安全集合類

    當多個線程同時訪問同一個臨界資源時,原子操作可能被破壞,會導致數(shù)據(jù)丟失, 就會觸發(fā)線程安全問題 臨界資源: 被多個線程同時訪問的對象 原子操作: 線程訪問臨界資源的過程中不可更改和缺失的操作 互斥鎖 每個對象都默認擁有互斥鎖, 該鎖默認不開啟. 當開啟互斥鎖之后

    2024年01月18日
    瀏覽(66)
  • 【JavaEE】JUC(Java.util.concurrent)常見類

    【JavaEE】JUC(Java.util.concurrent)常見類

    經過前面文章的學習我們大致了解了如何實現(xiàn)多線程編程和解決多線程編程中遇到的線程不安全問題, java.util.concurrent 是我們多線程編程的一個常用包,那么今天我將為大家分享 java.util.concurrent 包下的其他幾種常見的類。 ReentrantLock 是可重入互斥鎖,跟 synchronized 定位是類似

    2024年02月08日
    瀏覽(59)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包