自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

美團(tuán)終面:你確定CAS不加鎖嗎?

開(kāi)發(fā) 前端
我們以Java.util.concurrent中的AtomicInteger為例,看一下在不使用鎖的情況下是如何保證線程安全的。主要理解getAndIncrement方法,該方法的作用相當(dāng)于 ++i 操作。

CAS大家都知道,這是一項(xiàng)樂(lè)觀鎖技術(shù),是Compare And Swap的簡(jiǎn)稱,顧名思義就是先比較再替換。

雖然他叫樂(lè)觀鎖,但是我們都知道它是不需要加鎖的,在JDK1.5 中的JUC就是建立在CAS之上的。相對(duì)于synchronized這種阻塞算法,CAS是非阻塞算法的一種常見(jiàn)實(shí)現(xiàn)。所以J.U.C在性能上有了很大的提升。

我們以java.util.concurrent中的AtomicInteger為例,看一下在不使用鎖的情況下是如何保證線程安全的。主要理解getAndIncrement方法,該方法的作用相當(dāng)于 ++i 操作:

public class AtomicInteger extends Number implements java.io.Serializable {  
private volatile int value;
public final int get() {
return value;
}
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
}

getAndIncrement采用了CAS操作,每次從內(nèi)存中讀取數(shù)據(jù)然后將此數(shù)據(jù)和+1后的結(jié)果進(jìn)行CAS操作,如果成功就返回結(jié)果,否則重試直到成功為止。而compareAndSet利用unsafe的compareAndSwapInt方法實(shí)現(xiàn)的。

啥是Unsafe呢?

Unsafe是CAS的核心類。因?yàn)镴ava無(wú)法直接訪問(wèn)底層操作系統(tǒng),而是通過(guò)本地(native)方法來(lái)訪問(wèn)。不過(guò)盡管如此,JVM還是開(kāi)了一個(gè)后門,JDK中有一個(gè)類Unsafe,它提供了硬件級(jí)別的原子操作。

Unsafe是Java中一個(gè)底層類,包含了很多基礎(chǔ)的操作,比如數(shù)組操作、對(duì)象操作、內(nèi)存操作、CAS操作、線程(park)操作、柵欄(Fence)操作,JUC包、一些三方框架都使用Unsafe類來(lái)保證并發(fā)安全。

Unsafe類提供了硬件級(jí)別的原子操作,如CAS原子操作。

?但是,大家有沒(méi)有想過(guò)這樣的問(wèn)題:

硬件層面CAS又是如何保證原子性的呢?真的完全沒(méi)加鎖嗎?

拿比較常見(jiàn)的x86架構(gòu)的CPU來(lái)說(shuō),其實(shí) CAS 操作通常使用 cmpxchg 指令實(shí)現(xiàn)的。

可是為啥cmpxchg 指令能保證原子性呢?主要是有以下幾個(gè)方面的保障:

1.  cmpxchg 指令是一條原子指令。在 CPU 執(zhí)行 cmpxchg 指令時(shí),處理器會(huì)自動(dòng)鎖定總線,防止其他 CPU 訪問(wèn)共享變量,然后執(zhí)行比較和交換操作,最后釋放總線。

2.  cmpxchg 指令在執(zhí)行期間,CPU 會(huì)自動(dòng)禁止中斷。這樣可以確保 CAS 操作的原子性,避免中斷或其他干擾對(duì)操作的影響。

3.  cmpxchg 指令是硬件實(shí)現(xiàn)的,可以保證其原子性和正確性。CPU 中的硬件電路確保了 cmpxchg 指令的正確執(zhí)行,以及對(duì)共享變量的訪問(wèn)是原子的。

所以,在操作系統(tǒng)層面,CAS還是會(huì)加鎖的,通過(guò)加鎖的方式鎖定總線,避免其他CPU訪問(wèn)共享變量。

所以,解決并發(fā)問(wèn)題,歸根結(jié)底還得靠鎖!

責(zé)任編輯:姜華 來(lái)源: Hollis
相關(guān)推薦

2024-05-27 11:35:40

2024-04-01 00:00:00

Redis緩存服務(wù)消息隊(duì)列

2024-04-22 00:00:00

CASCPU硬件

2017-06-02 08:48:29

互斥鎖JavaCAS

2024-10-31 08:50:14

2022-08-27 13:50:44

TCP服務(wù)端函數(shù)

2022-09-12 15:55:57

TCP函數(shù)程序

2024-09-18 09:02:14

單核服務(wù)器線程切換

2023-04-21 13:57:38

Redis阻塞半自動(dòng)

2024-04-24 09:02:58

線程池面試鎖升級(jí)

2023-04-03 07:57:00

2021-09-09 19:08:49

JDK版本Java

2023-04-03 10:24:00

spring事務(wù)場(chǎng)景

2025-03-25 12:00:00

@Value?Spring開(kāi)發(fā)

2022-09-08 13:56:49

MySQL事務(wù)記錄鎖

2015-10-19 09:57:02

阿里美團(tuán)大眾

2023-07-13 09:16:47

循環(huán)隊(duì)列指針front?

2024-04-15 08:37:35

2022-08-24 07:44:53

流量系統(tǒng)數(shù)據(jù)

2023-07-27 07:28:04

存儲(chǔ)鏈表HashSet
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)