国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

CAS

meislzhua / 3167人閱讀

摘要:如果程序是在多處理器上運行,就為指令加上前綴。關于的鎖有如下種處理器自動保證基本內存操作的原子性首先處理器會自動保證基本的內存操作的原子性。使用緩存鎖保證原子性第二個機制是通過緩存鎖定保證原子性。

前言 概述

與鎖不同的是, CAS 是一種無鎖操作,一種無阻塞的算法,它實質上不能說是一種鎖,而是將 CPU 充分利用起來的一種算法

CAS 廣泛應用在數據結構中,JDK中的 java.util.concurrent 并發包就是在其操作下建立的

眾所周知,JAVA 作為一門高級語言,是不支持一些底層處理的,例如指針,內存控制等等,但大家可以看看 sun.misc.Unsafe 類,也是在它的支持下,JAVA 具備了對硬件級別原子操作的支持,這個包有很多應用,例如 java.util.concurrent.atomic 包下的原子類都是基于其實現 CAS 操作的

我的測試下,當線程數量不大時,CAS 要快于鎖,但線程數量很多很多時,CAS 卻更慢了

參考

http://blog.csdn.net/hsuxu/ar...
http://www.cnblogs.com/mickol...

CAS 概述

舉個例子,如 i++,它是分三步的

先取內存中的 i

再將 i 加上 1

最后將加完后的值賦給內存中的 i

但若在其賦值前,i 的內存值已經被其他線程修改,此處肯定會丟失數據,也就是說它是線程不安全的

如果給這個操作加上鎖,那代價未免也太大了,CAS 便可以更快地解決這個問題

原理

CAS 的原理其實很簡單,主要分三個參數

內存值 - 內存里的實際值

舊期望值 - 操作前的值

新值 - 操作后的值

CAS 的操作簡而言之就是 compare and swap

將內存值與舊期望值比較

若相等,則說明此值在操作中沒有被其他線程改變過,并將新值賦給內存值

若不等,則說明此值在操作中已經被其他線程改變過,并一直自旋直到相等

ABA 問題

簡而言之,ABA 問題就是,比如我取內存值 A,在我比較之前,它被其他人改成了 B,然后又被其他人改回了 A,而我之后再做比較,相等成立,但是又會造成數據丟失的問題

CAS 真正比較的應該是 值的狀態,而不是值的大小,我可以給值附帶一個 版本號,然后更新時對版本號進行值大小的 CAS 操作,或者附帶一個 時間戳也是一樣的,像現在數據庫大部分都是采用附加版本號的方法

大家也可以看看 java.util.concurrent.atomic.AtomicStampedReference 是怎么解決 ABA 問題的,在這里就不講述了

缺點

如果每個人都在自旋,CPU 的開銷將是巨大的,關于本人的測試,當線程數量很多很多時,CAS 會更慢就是這個原因

AtomicInteger

我們來看看 java.util.concurrent.atomic.AtomicInteger 是怎么實現原子操作的,其主要成員如下

// Unsafe 類實例,具體的在下一篇文章詳細講,這里先跳過
private static final Unsafe unsafe = Unsafe.getUnsafe();
// 值偏移量
private static final long valueOffset;
// 內部封裝值
private volatile int value;
// unsafe 初始化
static {
    try {
        valueOffset = unsafe.objectFieldOffset
            (AtomicInteger.class.getDeclaredField("value"));
    } catch (Exception ex) { 
        throw new Error(ex); 
    }
}

我們常用的 incrementAndGet 方法如下,在這里是直接調用 Unsafe 的 native 方法,實現硬件級別的原子操作,底層是用匯編實現的

public final int incrementAndGet() {
    return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
}

這個本地方法在openjdk中依次調用的c++代碼為:unsafe.cpp,atomic.cpp和atomicwindowsx86.inline.hpp。這個本地方法的最終實現在openjdk的如下位置:openjdk-7-fcs-src-b147-27jun2011openjdkhotspotsrcoscpuwindowsx86vm atomicwindowsx86.inline.hpp(對應于windows操作系統,X86處理器)。下面是對應于intel x86處理器的源代碼的片段:

// Adding a lock prefix to an instruction on MP machine
// VC++ doesn"t like the lock prefix to be on a single line
// so we can"t insert a label after the lock prefix.
// By emitting a lock prefix, we can define a label after it.
#define LOCK_IF_MP(mp) __asm cmp mp, 0  
                       __asm je L0      
                       __asm _emit 0xF0 
                       __asm L0:

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
  }
}

如上面源代碼所示,程序會根據當前處理器的類型來決定是否為cmpxchg指令添加lock前綴。如果程序是在多處理器上運行,就為cmpxchg指令加上lock前綴(lock cmpxchg)。反之,如果程序是在單處理器上運行,就省略lock前綴(單處理器自身會維護單處理器內的順序一致性,不需要lock前綴提供的內存屏障效果)。

CPU

關于CPU的鎖有如下3種:

處理器自動保證基本內存操作的原子性

首先處理器會自動保證基本的內存操作的原子性。處理器保證從系統內存當中讀取或者寫入一個字節是原子的,意思是當一個處理器讀取一個字節時,其他處理器不能訪問這個字節的內存地址。奔騰6和最新的處理器能自動保證單處理器對同一個緩存行里進行16/32/64位的操作是原子的,但是復雜的內存操作處理器不能自動保證其原子性,比如跨總線寬度,跨多個緩存行,跨頁表的訪問。但是處理器提供總線鎖定和緩存鎖定兩個機制來保證復雜內存操作的原子性

使用總線鎖保證原子性

第一個機制是通過總線鎖保證原子性。如果多個處理器同時對共享變量進行讀改寫(i++就是經典的讀改寫操作)操作,那么共享變量就會被多個處理器同時進行操作,這樣讀改寫操作就不是原子的,操作完之后共享變量的值會和期望的不一致,舉個例子:如果i=1,我們進行兩次i++操作,我們期望的結果是3,但是有可能結果是2,如圖

原因是有可能多個處理器同時從各自的緩存中讀取變量i,分別進行加一操作,然后分別寫入系統內存當中。那么想要保證讀改寫共享變量的操作是原子的,就必須保證CPU1讀改寫共享變量的時候,CPU2不能操作緩存了該共享變量內存地址的緩存。

處理器使用總線鎖就是來解決這個問題的。所謂總線鎖就是使用處理器提供的一個LOCK#信號,當一個處理器在總線上輸出此信號時,其他處理器的請求將被阻塞住,那么該處理器可以獨占使用共享內存。

使用緩存鎖保證原子性

第二個機制是通過緩存鎖定保證原子性。在同一時刻我們只需保證對某個內存地址的操作是原子性即可,但總線鎖定把CPU和內存之間通信鎖住了,這使得鎖定期間,其他處理器不能操作其他內存地址的數據,所以總線鎖定的開銷比較大,最近的處理器在某些場合下使用緩存鎖定代替總線鎖定來進行優化。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/67245.html

相關文章

  • CAS 5.2.x 單點登錄 - 搭建服務端和客戶端

    摘要:一簡介單點登錄,簡稱為,是目前比較流行的企業業務整合的解決方案之一。客戶端攔截未認證的用戶請求,并重定向至服務端,由服務端對用戶身份進行統一認證。三搭建客戶端在官方文檔中提供了客戶端樣例,即。 一、簡介 單點登錄(Single Sign On),簡稱為 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,用戶只需要登錄一次就可以訪問所有相互信任的應用系...

    Lin_YT 評論0 收藏0
  • 統一認證 - Apereo CAS 客戶端的集成以及小結

    摘要:所以客戶端的集成主要是單點登錄的集成,客戶端指定需要做安全認證的頁面,然后的安全包檢測校驗用戶登錄情況,并自動與登錄頁面進行跳轉交互。提供了很多配置的方式,有,,以及其他可查官網。但高度自由的一如既往的,沒有提供可視化操作的界面。 前兩篇介紹了Apereo CAS以及服務器端的安裝,但還不夠完整,服務端還沒有Application真正用起來呢!這篇文章將介紹怎么用起來 集成的目的 客戶...

    AbnerMing 評論0 收藏0
  • spring系列---CAS客戶端與SpringSecurity集成

    摘要:客戶端與集成指定端口請求路徑用于單點退出,該過濾器用于實現單點登出功能,可選配置該過濾器用于實現單點登出功能,可選配置。該過濾器使得開發者可以通過來獲取用戶的登錄名。 CAS客戶端與SpringSecurity集成 pom.xml org.springframework spring-context 4.3.9....

    hizengzeng 評論0 收藏0
  • 從http驗證流程解析CAS單點登錄

    JAVA單點登錄有好多種方式,譬如用cookie的domain做,用中間代理做等等,但都需要自行做許多開發工作。而其中耶魯大學的開源項目CAS提供了一個一站式解決方案,只需很少的擴展即可輕松實現企業級單點登錄。基礎知識網上其他挺多的,這里我就不詳述了。本文通過分析http請求過程中httpheader,cookie等數據剖析了cas(非代理模式,默認驗證邏輯。其他如restletAPI等可擴展邏輯...

    honhon 評論0 收藏0
  • 前后端分離下的CAS跨域流程分析

    摘要:這種情況通常發生在反向代理的時候,前端發起請求代理服務器,代理服務器發起請求到,這時候就容易導致域名不一致,請一定要注意這點。 寫在最前 前后端分離其實有兩類: 開發階段使用dev-server,生產階段是打包成靜態文件整個放入后端項目中。 開發階段使用dev-server,生產階段是打包成靜態文件放入單獨的靜態資源服務器中,如nginx。 這兩種方案最大的區別就是生產階段。由于第...

    ckllj 評論0 收藏0
  • 前后端分離下的CAS跨域流程分析

    摘要:這種情況通常發生在反向代理的時候,前端發起請求代理服務器,代理服務器發起請求到,這時候就容易導致域名不一致,請一定要注意這點。 寫在最前 前后端分離其實有兩類: 開發階段使用dev-server,生產階段是打包成靜態文件整個放入后端項目中。 開發階段使用dev-server,生產階段是打包成靜態文件放入單獨的靜態資源服務器中,如nginx。 這兩種方案最大的區別就是生產階段。由于第...

    DevTalking 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<