日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java死锁、活锁,悲观锁、乐观锁

發(fā)布時間:2024/8/26 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java死锁、活锁,悲观锁、乐观锁 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1、死鎖與活鎖的區(qū)別,死鎖與饑餓的區(qū)別?

死鎖:是指兩個或兩個以上的進程(或線程)在執(zhí)行過程中,因爭奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進下去。?

產(chǎn)生死鎖的必要條件:?

互斥條件:所謂互斥就是進程在某一時間內(nèi)獨占資源。

請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。?

不剝奪條件:進程已獲得資源,在末使用完之前,不能強行剝奪。??

循環(huán)等待條件:若干進程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。

活鎖:任務(wù)或者執(zhí)行者沒有被阻塞,由于某些條件沒有滿足,導(dǎo)致一直重復(fù)嘗試,失敗,嘗試,失敗。

活鎖和死鎖的區(qū)別在于,處于活鎖的實體是在不斷的改變狀態(tài),所謂的“活”, 而處于死鎖的實體表現(xiàn)為等待;活鎖有可能自行解開,死鎖則不能。

饑餓:一個或者多個線程因為種種原因無法獲得所需要的資源,導(dǎo)致一直無法執(zhí)行的狀態(tài)。?

Java中導(dǎo)致饑餓的原因:?

高優(yōu)先級線程吞噬所有的低優(yōu)先級線程的CPU時間。?

線程被永久堵塞在一個等待進入同步塊的狀態(tài),因為其他線程總是能在它之前持續(xù)地對該同步塊進行訪問。?

線程在等待一個本身也處于永久等待完成的對象(比如調(diào)用這個對象的wait方法),因為其他線程總是被持續(xù)地獲得喚醒。

2、樂觀鎖和悲觀鎖的理解及如何實現(xiàn),有哪些實現(xiàn)方式?

悲觀鎖:總是假設(shè)最壞的情況,每次去拿數(shù)據(jù)的時候都認為別人會修改,所以每次在拿數(shù)據(jù)的時候都會上鎖,這樣別人想拿這個數(shù)據(jù)就會阻塞直到它拿到鎖。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。再比如Java里面的同步原語synchronized關(guān)鍵字的實現(xiàn)也是悲觀鎖。

樂觀鎖:顧名思義,就是很樂觀,每次去拿數(shù)據(jù)的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數(shù)據(jù),可以使用版本號等機制。樂觀鎖適用于多讀的應(yīng)用類型,這樣可以提高吞吐量,像數(shù)據(jù)庫提供的類似于write_condition機制,其實都是提供的樂觀鎖。在Java中java.util.concurrent.atomic包下面的原子變量類就是使用了樂觀鎖的一種實現(xiàn)方式CAS實現(xiàn)的。

樂觀鎖的實現(xiàn)方式:?

使用版本標識來確定讀到的數(shù)據(jù)與提交時的數(shù)據(jù)是否一致。提交后修改版本標識,不一致時可以采取丟棄和再次嘗試的策略。?

java中的Compare and Swap即CAS ,當多個線程嘗試使用CAS同時更新同一個變量時,只有其中一個線程能更新變量的值,而其它線程都失敗,失敗的線程并不會被掛起,而是被告知這次競爭中失敗,并可以再次嘗試。 CAS 操作中包含三個操作數(shù) —— 需要讀寫的內(nèi)存位置(V)、進行比較的預(yù)期原值(A)和擬寫入的新值(B)。如果內(nèi)存位置V的值與預(yù)期原值A(chǔ)相匹配,那么處理器會自動將該位置值更新為新值B。否則處理器不做任何操作。

CAS缺點:??

ABA問題:?

比如說一個線程one從內(nèi)存位置V中取出A,這時候另一個線程two也從內(nèi)存中取出A,并且two進行了一些操作變成了B,然后two又將V位置的數(shù)據(jù)變成A,這時候線程one進行CAS操作發(fā)現(xiàn)內(nèi)存中仍然是A,然后one操作成功。盡管線程one的CAS操作成功,但可能存在潛藏的問題。從Java1.5開始JDK的atomic包里提供了一個類AtomicStampedReference來解決ABA問題。?

循環(huán)時間長開銷大:?

對于資源競爭嚴重(線程沖突嚴重)的情況,CAS自旋的概率會比較大,從而浪費更多的CPU資源,效率低于synchronized。?

只能保證一個共享變量的原子操作:?

當對一個共享變量執(zhí)行操作時,我們可以使用循環(huán)CAS的方式來保證原子操作,但是對多個共享變量操作時,循環(huán)CAS就無法保證操作的原子性,這個時候就可以用鎖。

3、SynchronizedMap和ConcurrentHashMap有什么區(qū)別?

SynchronizedMap一次鎖住整張表來保證線程安全,所以每次只能有一個線程來訪為map。

ConcurrentHashMap使用分段鎖來保證在多線程下的性能。ConcurrentHashMap中則是一次鎖住一個桶。ConcurrentHashMap默認將hash表分為16個桶,諸如get,put,remove等常用操作只鎖當前需要用到的桶。這樣,原來只能一個線程進入,現(xiàn)在卻能同時有16個寫線程執(zhí)行,并發(fā)性能的提升是顯而易見的。?

另外ConcurrentHashMap使用了一種不同的迭代方式。在這種迭代方式中,當iterator被創(chuàng)建后集合再發(fā)生改變就不再是拋出ConcurrentModificationException,取而代之的是在改變時new新的數(shù)據(jù)從而不影響原有的數(shù)據(jù) ,iterator完成后再將頭指針替換為新的數(shù)據(jù) ,這樣iterator線程可以使用原來老的數(shù)據(jù),而寫線程也可以并發(fā)的完成改變。

總結(jié)

以上是生活随笔為你收集整理的Java死锁、活锁,悲观锁、乐观锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。