摘要:先比較,發(fā)現(xiàn)與預(yù)期一致,說(shuō)明沒(méi)有其他線程改動(dòng)過(guò),于是就交換如果不一致說(shuō)明改動(dòng)過(guò),就再來(lái)一次,如此往復(fù)。所謂無(wú)鎖是在層面上沒(méi)有鎖,但其實(shí)在操作系統(tǒng)的指令層面是加了鎖的。這個(gè)鎖比上的鎖性能好很多。
CAS(CompareAndSwap)顧名思義比較再交換。先比較,發(fā)現(xiàn)與預(yù)期一致,說(shuō)明沒(méi)有其他線程改動(dòng)過(guò),于是就交換;如果不一致說(shuō)明改動(dòng)過(guò),就再來(lái)一次,如此往復(fù)。
int prev, next; do { prev = get(); next = accumulatorFunction.applyAsInt(prev, x); } while (!compareAndSet(prev, next)); return next;
這是一種自旋的方式保證線程安全,可是compareAndSet這個(gè)比較再交換是原子的嗎?先比較發(fā)現(xiàn)與預(yù)期一致了,準(zhǔn)備交換的時(shí)候另一個(gè)線程來(lái)改了怎么辦?
點(diǎn)進(jìn)去看源碼:
public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); }
這個(gè)unsafe的方法都是native方法,
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
只能打開(kāi)openJDK看源碼了
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) UnsafeWrapper("Unsafe_CompareAndSwapInt"); oop p = JNIHandles::resolve(obj); jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); return (jint)(Atomic::cmpxchg(x, addr, e)) == e; UNSAFE_END
核心方法是cmpxchg方法
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { // alternative for InterlockedCompareExchange int mp = os::is_MP(); __asm { mov edx, dest mov ecx, exchange_value mov eax, compare_value LOCK_IF_MP(mp) cmpxchg dword ptr [edx], ecx } }
原來(lái)LOCK_IF_MP這里加了鎖,才保證了原子性。所謂“無(wú)鎖”是在Java層面上沒(méi)有鎖,但其實(shí)在操作系統(tǒng)的CPU指令層面是加了鎖的。這個(gè)鎖比java上的鎖性能好很多。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/75080.html
摘要:每一個(gè)被鎖住的對(duì)象都會(huì)和一個(gè)關(guān)聯(lián)對(duì)象頭的中的指向的起始地址,同時(shí)中有一個(gè)字段存放擁有該鎖的線程的唯一標(biāo)識(shí),表示該鎖被這個(gè)線程占用。 jdk 6 對(duì)鎖進(jìn)行了優(yōu)化,讓他看起來(lái)不再那么笨重,synchronized有三種形式:偏向鎖,輕量級(jí)鎖,重量級(jí)鎖. 介紹三種鎖之前,引入幾個(gè)接下來(lái)會(huì)出現(xiàn)的概念 mark work: 對(duì)象頭,對(duì)象頭中存儲(chǔ)了一些對(duì)象的信息,這個(gè)是鎖的根本,任何鎖都需要依賴(lài)m...
摘要:前情提要深入理解內(nèi)存模型四鎖的釋放獲取建立的關(guān)系鎖是并發(fā)編程中最重要的同步機(jī)制。鎖內(nèi)存語(yǔ)義的實(shí)現(xiàn)本文將借助的源代碼,來(lái)分析鎖內(nèi)存語(yǔ)義的具體實(shí)現(xiàn)機(jī)制。請(qǐng)看下篇深入理解內(nèi)存模型六 前情提要 深入理解Java內(nèi)存模型(四)—— volatile 鎖的釋放-獲取建立的happens before 關(guān)系 鎖是java并發(fā)編程中最重要的同步機(jī)制。鎖除了讓臨界區(qū)互斥執(zhí)行外,還可以讓釋放鎖的線程向...
摘要:鎖的部分細(xì)節(jié)不同場(chǎng)景鎖的表現(xiàn)不同獨(dú)占共享讀寫(xiě)分布式鎖的簡(jiǎn)單實(shí)現(xiàn)分布式鎖實(shí)現(xiàn)的三個(gè)核心要素加鎖最簡(jiǎn)單的方法是使用命令。嘗試獲取分布式鎖客戶(hù)端鎖線程超期時(shí)間是否獲取成功釋放分布式鎖客戶(hù)端鎖請(qǐng)求標(biāo)識(shí)是否釋放成功 鎖的由來(lái): 多線程環(huán)境中,經(jīng)常遇到多個(gè)線程訪問(wèn)同一個(gè) 共享資源 ,這時(shí)候作為開(kāi)發(fā)者必須考慮如何維護(hù)數(shù)據(jù)一致性,這就需要某種機(jī)制來(lái)保證只有滿(mǎn)足某個(gè)條件(獲取鎖成功)的線程才能訪問(wèn)資源...
摘要:第三天,太監(jiān)傳話欽天監(jiān)求見(jiàn)一日無(wú)事。第四天,欽天監(jiān)一日無(wú)事。然后所有的競(jìng)爭(zhēng)線程放棄自旋,逐個(gè)插入到對(duì)象里的一個(gè)隊(duì)列尾部,進(jìn)入阻塞狀態(tài)。 微信公眾號(hào):IT一刻鐘大型現(xiàn)實(shí)非嚴(yán)肅主義現(xiàn)場(chǎng)一刻鐘與你分享優(yōu)質(zhì)技術(shù)架構(gòu)與見(jiàn)聞,做一個(gè)有劇情的程序員關(guān)注可第一時(shí)間了解更多精彩內(nèi)容,定期有福利相送喲。 showImg(https://segmentfault.com/img/bVbrgsJ?w=900...
閱讀 2648·2021-11-23 09:51
閱讀 3411·2021-11-22 15:22
閱讀 1937·2021-11-18 13:22
閱讀 2386·2021-09-24 09:48
閱讀 1367·2019-08-29 13:58
閱讀 1368·2019-08-26 13:39
閱讀 2510·2019-08-26 10:48
閱讀 3103·2019-08-26 10:21