摘要:與同步方式在多線程情況下,可以采用同步阻塞悲觀鎖或樂(lè)觀鎖的方式實(shí)現(xiàn)業(yè)務(wù),具體要看業(yè)務(wù)場(chǎng)景,如果重試的代價(jià)很小,那用是合適的,但如果每次重試都需要花費(fèi)大量的時(shí)間或資源,那應(yīng)該采用同步方式。
CAS介紹
CAS - Compare And Swap (Compare And Set, Check And Set)
wikipedia的描述如下:
比較并交換(compare and swap, CAS),是原子操作的一種,可用于在多線程編程中實(shí)現(xiàn)不被打斷的數(shù)據(jù)交換操作,從而避免多線程同時(shí)改寫(xiě)某一數(shù)據(jù)時(shí)由于執(zhí)行順序不確定性以及中斷的不可預(yù)知性產(chǎn)生的數(shù)據(jù)不一致問(wèn)題。 該操作通過(guò)將內(nèi)存中的值與指定數(shù)據(jù)進(jìn)行比較,當(dāng)數(shù)值一樣時(shí)將內(nèi)存中的數(shù)據(jù)替換為新的值。
Java在sun.misc.Unsafe類庫(kù)里面的CAS實(shí)現(xiàn)。
以下源碼摘自java.util.concurrent.locks.AbstractQueuedSynchronizer。
/** * Atomically sets synchronization state to the given updated * value if the current state value equals the expected value. * This operation has memory semantics of a {@code volatile} read * and write. * * @param expect the expected value * @param update the new value * @return {@code true} if successful. False return indicates that the actual * value was not equal to the expected value. */ protected final boolean compareAndSetState(int expect, int update) { // See below for intrinsics setup to support this //this: 當(dāng)前對(duì)象 //stateOffSet: 偏移量,聲明在下面已貼出 //expect: 期待值 //update: 更新值 //如果stateOffSet的值與expect相等,則將stateOffset的值更新為update;并返回true。 //否則不更新,并返回false。 return unsafe.compareAndSwapInt(this, stateOffset, expect, update); } ...... private static final long stateOffset; static { try { stateOffset = unsafe.objectFieldOffset (AbstractQueuedSynchronizer.class.getDeclaredField("state")); ...... } catch (Exception ex) { throw new Error(ex); } }CAS與同步方式
在多線程情況下,可以采用同步阻塞(悲觀鎖)或CAS(樂(lè)觀鎖)的方式實(shí)現(xiàn)業(yè)務(wù),具體要看業(yè)務(wù)場(chǎng)景,如果重試的代價(jià)很小,那用CAS是合適的,但如果每次重試都需要花費(fèi)大量的時(shí)間或資源,那應(yīng)該采用同步方式。
以下是2種方式的簡(jiǎn)單舉例:
class MyLock { private boolean locked = false; public synchronized boolean lock() { if(!locked) { locked = true; return true; } return false; } }
public static class MyLock { private AtomicBoolean locked = new AtomicBoolean(false); public boolean lock() { return locked.compareAndSet(false, true); } }CAS缺點(diǎn) - ABA問(wèn)題
進(jìn)程P1讀取了一個(gè)數(shù)值A(chǔ) P1被掛起(時(shí)間片耗盡、中斷等),進(jìn)程P2開(kāi)始執(zhí)行 P2修改數(shù)值A(chǔ)為數(shù)值B,然后又修改回A P1被喚醒,比較后發(fā)現(xiàn)數(shù)值A(chǔ)沒(méi)有變化,程序繼續(xù)執(zhí)行。
解決思路:在每次更新的同時(shí)附上版本號(hào),如:1A -> 2B -> 3A。JDK1.5開(kāi)始新增的java.util.concurrent.atomic.AtomicStampedReference就是一種實(shí)現(xiàn)方式。
Redis中的CASRedis可以使用WATCH來(lái)實(shí)現(xiàn)對(duì)事務(wù)中鍵(可以是多個(gè)鍵)的監(jiān)視,如果至少有一個(gè)鍵在EXEC執(zhí)行前被改動(dòng),那么整個(gè)事務(wù)都會(huì)被取消, EXEC返回nil-reply來(lái)表示事務(wù)已經(jīng)失敗。
具體參見(jiàn):Redis - 事務(wù)(transactions)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69256.html
摘要:一簡(jiǎn)介單點(diǎn)登錄,簡(jiǎn)稱為,是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之一??蛻舳藬r截未認(rèn)證的用戶請(qǐng)求,并重定向至服務(wù)端,由服務(wù)端對(duì)用戶身份進(jìn)行統(tǒng)一認(rèn)證。三搭建客戶端在官方文檔中提供了客戶端樣例,即。 一、簡(jiǎn)介 單點(diǎn)登錄(Single Sign On),簡(jiǎn)稱為 SSO,是目前比較流行的企業(yè)業(yè)務(wù)整合的解決方案之一。SSO的定義是在多個(gè)應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問(wèn)所有相互信任的應(yīng)用系...
摘要:所以客戶端的集成主要是單點(diǎn)登錄的集成,客戶端指定需要做安全認(rèn)證的頁(yè)面,然后的安全包檢測(cè)校驗(yàn)用戶登錄情況,并自動(dòng)與登錄頁(yè)面進(jìn)行跳轉(zhuǎn)交互。提供了很多配置的方式,有,,以及其他可查官網(wǎng)。但高度自由的一如既往的,沒(méi)有提供可視化操作的界面。 前兩篇介紹了Apereo CAS以及服務(wù)器端的安裝,但還不夠完整,服務(wù)端還沒(méi)有Application真正用起來(lái)呢!這篇文章將介紹怎么用起來(lái) 集成的目的 客戶...
摘要:客戶端與集成指定端口請(qǐng)求路徑用于單點(diǎn)退出,該過(guò)濾器用于實(shí)現(xiàn)單點(diǎn)登出功能,可選配置該過(guò)濾器用于實(shí)現(xiàn)單點(diǎn)登出功能,可選配置。該過(guò)濾器使得開(kāi)發(fā)者可以通過(guò)來(lái)獲取用戶的登錄名。 CAS客戶端與SpringSecurity集成 pom.xml org.springframework spring-context 4.3.9....
JAVA單點(diǎn)登錄有好多種方式,譬如用cookie的domain做,用中間代理做等等,但都需要自行做許多開(kāi)發(fā)工作。而其中耶魯大學(xué)的開(kāi)源項(xiàng)目CAS提供了一個(gè)一站式解決方案,只需很少的擴(kuò)展即可輕松實(shí)現(xiàn)企業(yè)級(jí)單點(diǎn)登錄?;A(chǔ)知識(shí)網(wǎng)上其他挺多的,這里我就不詳述了。本文通過(guò)分析http請(qǐng)求過(guò)程中httpheader,cookie等數(shù)據(jù)剖析了cas(非代理模式,默認(rèn)驗(yàn)證邏輯。其他如restletAPI等可擴(kuò)展邏輯...
摘要:這種情況通常發(fā)生在反向代理的時(shí)候,前端發(fā)起請(qǐng)求代理服務(wù)器,代理服務(wù)器發(fā)起請(qǐng)求到,這時(shí)候就容易導(dǎo)致域名不一致,請(qǐng)一定要注意這點(diǎn)。 寫(xiě)在最前 前后端分離其實(shí)有兩類: 開(kāi)發(fā)階段使用dev-server,生產(chǎn)階段是打包成靜態(tài)文件整個(gè)放入后端項(xiàng)目中。 開(kāi)發(fā)階段使用dev-server,生產(chǎn)階段是打包成靜態(tài)文件放入單獨(dú)的靜態(tài)資源服務(wù)器中,如nginx。 這兩種方案最大的區(qū)別就是生產(chǎn)階段。由于第...
摘要:這種情況通常發(fā)生在反向代理的時(shí)候,前端發(fā)起請(qǐng)求代理服務(wù)器,代理服務(wù)器發(fā)起請(qǐng)求到,這時(shí)候就容易導(dǎo)致域名不一致,請(qǐng)一定要注意這點(diǎn)。 寫(xiě)在最前 前后端分離其實(shí)有兩類: 開(kāi)發(fā)階段使用dev-server,生產(chǎn)階段是打包成靜態(tài)文件整個(gè)放入后端項(xiàng)目中。 開(kāi)發(fā)階段使用dev-server,生產(chǎn)階段是打包成靜態(tài)文件放入單獨(dú)的靜態(tài)資源服務(wù)器中,如nginx。 這兩種方案最大的區(qū)別就是生產(chǎn)階段。由于第...
閱讀 3067·2021-11-16 11:45
閱讀 3598·2021-09-29 09:34
閱讀 713·2021-08-16 10:50
閱讀 1581·2019-08-30 15:52
閱讀 1972·2019-08-30 15:45
閱讀 868·2019-08-29 15:23
閱讀 1935·2019-08-26 13:51
閱讀 3308·2019-08-26 12:23