CAS是樂觀鎖的一種實(shí)現(xiàn)方式象泵。而CAS中包含自旋鎖琼腔,當(dāng)預(yù)期值和內(nèi)存值不相同的時(shí)候瑰枫,一般情況下是一個(gè)自旋操作,即不斷的重試丹莲。
自旋鎖概念:當(dāng)一個(gè)線程在獲取鎖的時(shí)候躁垛,如果鎖已經(jīng)被其他線程獲取,那么該線程將循環(huán)等待圾笨,然后不斷的判斷鎖是否能夠被成功獲取教馆,直到獲取到鎖才會(huì)退出循環(huán)。
嘗試獲取鎖的線程一直處于活躍狀態(tài)擂达,但是并沒有執(zhí)行任何有效的任務(wù)土铺,這種鎖會(huì)造成busy-waiting.
public class SpinLock {
? ?private AtomicReference<Thread> cas = new AtomicReference<Thread>();
? ? public void lock() {
? ?? ? Thread current = Thread.currentThread();
? ? ? ? // 利用CAS
? ?? ? while (!cas.compareAndSet(null, current)) {
? ?? ?? ?? ? // DO nothing
? ?? ?}
? ? }
? ? public void unlock() {
? ?? ? Thread current = Thread.currentThread();
? ?? ? cas.compareAndSet(current, null);
? ? }
}
lock()方法利用的CAS,當(dāng)?shù)谝粋€(gè)線程A獲取鎖的時(shí)候,能夠成功獲取到悲敷,不會(huì)進(jìn)入while循環(huán)究恤,如果此時(shí)線程A沒有釋放鎖,另一個(gè)線程B又來獲取鎖后德,此時(shí)由于不滿足CAS部宿,所以就會(huì)進(jìn)入while循環(huán),不斷判斷是否滿足CAS瓢湃,直到A線程調(diào)用unlock方法釋放了該鎖理张。
自旋鎖不會(huì)使線程狀態(tài)發(fā)生切換,一直處于用戶態(tài)绵患,即線程一直都是active的雾叭;不會(huì)使線程進(jìn)入阻塞狀態(tài),減少了不必要的上下文切換落蝙,執(zhí)行速度快
非自旋鎖在獲取不到鎖的時(shí)候會(huì)進(jìn)入阻塞狀態(tài)织狐,從而進(jìn)入內(nèi)核態(tài),當(dāng)獲取到鎖的時(shí)候需要從內(nèi)核態(tài)恢復(fù)筏勒,需要線程上下文切換移迫。 (線程被阻塞后便進(jìn)入內(nèi)核(Linux)調(diào)度狀態(tài),這個(gè)會(huì)導(dǎo)致系統(tǒng)在用戶態(tài)與內(nèi)核態(tài)之間來回切換管行,嚴(yán)重影響鎖的性能)