淺談Java非阻塞同步機制和CAS
什么是非阻塞同步
非阻塞同步的意思是多個線程在競爭相同的數(shù)據(jù)時候不會發(fā)生阻塞,從而能夠在更加細粒度的維度上進行協(xié)調(diào),從而極大的減少線程調(diào)度的開銷,從而提升效率。非阻塞算法不存在鎖的機制也就不存在死鎖的問題。
在基于鎖的算法中,如果一個線程持有了鎖,那么其他的線程將無法進行下去。使用鎖雖然可以保證對資源的一致性訪問,但是在掛起和恢復線程的執(zhí)行過程中存在非常大的開銷,如果鎖上面存在著大量的競爭,那么有可能調(diào)度開銷比實際工作開銷還要高。
悲觀鎖和樂觀鎖
我們知道獨占鎖是一個悲觀鎖,悲觀鎖的意思就是假設(shè)最壞的情況,如果你不鎖定該資源,那么就有其他的線程會修改該資源。悲觀鎖雖然可以保證任務的順利執(zhí)行,但是效率不高。
樂觀鎖就是假設(shè)其他的線程不會更改要處理的資源,但是我們在更新資源的時候需要判斷該資源是否被別的線程所更改。如果被更改那么更新失敗,我們可以重試,如果沒有被更改,那么更新成功。
使用樂觀鎖的前提是假設(shè)大多數(shù)時間系統(tǒng)對資源的更新是不會產(chǎn)生沖突的。
樂觀鎖的原子性比較和更新操作,一般都是由底層的硬件支持的。
CAS
大多數(shù)的處理器都實現(xiàn)了一個CAS指令(compare and swap),通常來說一個CAS接收三個參數(shù),數(shù)據(jù)的現(xiàn)值V,進行比較的值A(chǔ),準備寫入的值B。只有當V和A相等的時候,才會寫入B。無論是否寫入成功,都會返回V。翻譯過來就是“我認為V現(xiàn)在的值是A,如果是那么將V的值更新為B,否則不修改V的值,并告訴我現(xiàn)在V的值是多少?!?/p>
這就是CAS的含義,JDK中的并發(fā)類是通過使用Unsafe類來使用CAS的,我們可以自己構(gòu)建一個并發(fā)類,如下所示:
public class CasCounter {
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
private volatile int value;
static {
try {
valueOffset = unsafe.objectFieldOffset
(CasCounter.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
public CasCounter(int initialValue) {
value = initialValue;
}
public CasCounter() {
}
public final int get() {
return value;
}
public final void set(int newValue) {
value = newValue;
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
}
上面的例子中,我們定義了一個原子操作compareAndSet, 它內(nèi)部調(diào)用了unsafe的compareAndSwapInt方法。
看起來上面的CAS使用比直接使用鎖復雜,但實際上在JVM中實現(xiàn)鎖定時需要遍歷JVM中一條非常復雜的代碼路徑,并可能導致操作系統(tǒng)級的鎖定,線程掛機和上下文切換等操作。在最好的情況下,鎖定需要執(zhí)行一次CAS命令。
CAS的主要缺點就是需要調(diào)用者自己來處理競爭問題(重試,回退,放棄),而在鎖中可以自動處理這些問題。
前面的文章我們也講到了原子變量,原子變量的底層就是使用CAS。
以上就是淺談Java非阻塞同步機制和CAS的詳細內(nèi)容,更多關(guān)于Java非阻塞同步機制和CAS的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java基于MySQL實現(xiàn)學生管理系統(tǒng)
這篇文章主要為大家詳細介紹了Java基于MySQL實現(xiàn)學生管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01
MyBatis各種類型查詢數(shù)據(jù)參數(shù)綁定的實現(xiàn)
本文主要介紹了MyBatis各種類型查詢數(shù)據(jù)參數(shù)綁定的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-06-06
如何在Spring中使用編碼方式動態(tài)配置Bean詳解
這篇文章主要給大家介紹了關(guān)于如何在Spring中使用編碼方式動態(tài)配置Bean的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-05-05
Java實現(xiàn)飛機航班管理系統(tǒng)的思路詳解
這篇文章主要介紹了Java實現(xiàn)飛機航班管理系統(tǒng)的思路詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
Spring Cloud Eureka 注冊與發(fā)現(xiàn)操作步驟詳解
這篇文章主要介紹了Spring Cloud Eureka 注冊與發(fā)現(xiàn)操作步驟詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03
SpringBoot接口數(shù)據(jù)加解密實戰(zhàn)記錄
現(xiàn)今對于大多數(shù)公司來說,信息安全工作尤為重要,下面這篇文章主要給大家介紹了關(guān)于SpringBoot接口數(shù)據(jù)加解密的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-07-07
Java框架解說之BIO NIO AIO不同IO模型演進之路
網(wǎng)上很多IO資料,對新手來說,越看越暈。根據(jù)自己的理解,總結(jié)對比了一下BIO、NIO、AIO,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-10-10

