STM 軟體事務記憶體——本質是為提高並發,通過事務來管理記憶體的讀寫訪問以避免鎖的使用

來源:互聯網
上載者:User

標籤:recover   center   訊息   png   並發控制   body   線程   指標傳遞   bsp   

對Java程式員來說,我們對物件導向的編程(OOP)自然都是爛熟於胸的,但語言也極大地影響了我們構建物件導向應用程式的方式。(現在的OOP已經和Alan Kay當初創造這個詞時候的初衷大不相同了,他的主要思想是採用訊息傳遞並消滅所有狀態資料(他認為,系統是由一些類似於生物細胞那樣的對象構成的,這些對象通過訊息傳遞進行通訊,且無需持有任何狀態)——go語言)

對於Java程式員來說,當我們順著指標或引用找到某個執行個體的時候,實際上是登入到了持有其狀態的一塊記憶體上,於是在那個位置上操縱資料也就成了自然而然的事了。該位置即代表了對象執行個體及其所包含的資料。將實體與狀態進行合并最初看起來是非常簡單且易於理解的,但從並發的角度來看,這種做法其實有很多嚴重的不良後果。例如,如果我們需要實現一個列印銀行賬戶詳情(資金數量、當前餘額、交易資訊、最小餘額等等)的程式,我們就會碰到很多並發相關的問題。你會發現手頭待處理的引用其實是一個隨時都可能發生變化的狀態的代理。所以當我們查看賬戶資訊的時候,就需要通過加鎖來阻止其他線程對賬戶內容進行修改,而這也必將導致並發度的大幅下降。但問題並不是從加鎖的那一刻才開始出現的,而是在我們把賬戶的實體與其狀態合并的時候就已經存在了。

我們曾經被告知說物件導向的編程是對真實世界的建模。但悲催的是,真實世界與OO範式所試圖構建的模型實際是大相徑庭的。因為在真實的世界中,狀態是不變的,而實體卻是不斷變化的。接下來我們將討論這種說法為何是正確的。

將實體與狀態分離

你能快速告訴我Google的股價現在是多少嗎?我們當然可以說從證券市場開市的那一刻起股價就是在不斷變化的。舉一個簡單的例子,2010年12月10日Google的收盤價是592美元,並且這個數字已經被載入史冊、是不會再改變了。當然,Google今天的股價和那天已經完全不同了。而如果過幾分鐘之後再來查看Google的股價(假設證券市場是開市的),我們就會看到一個不一樣的值,但之前的那個值其實並沒有改變。從現在開始,我們得改變一下我們對對象的認識,而這也將同時改變我們使用對象的方式。後面我們會看到,把對象的實體與其不可變狀態值進行分離的做法將如何協助我們實現鎖無關編程、提高並發度、同時最大程度地降低競爭。

將實體與狀態分離絕對是一個天才的構想,這是STM模型過程中所採用的一個非常關鍵的步驟。假定我們的Google股票對象由兩部分組成:第一部分用於表示該股的實體,其中包含一個指向第二部分的指標。第二部分則包含了該股最新股價,其中儲存股價的變數即為不可變狀態, 1所示。

 

圖 1 將可變實體部分與不可變狀態值進行分離

一旦接收到一個新的股價資訊,我們就可以將其放入曆史價格指數中。由於舊的股價是不可變的,所以我們可以將其共用出去供所有線程訪問。Google股票對象就可以多快好省地對外提供資料讀取服務。而一旦有新的資料準備就緒之後,我們可以快速更改實體中的指標,以使其指向儲存新股價的欄位。實體與狀態分離的做法對於並發來說也是一大福音。因為採用了這種方法之後,我們就可以不用阻塞任何查詢股價的請求了。由於狀態是不會變的,所以我們可以欣然將其指標傳遞給發出查詢請求的線程。

 STM中的事務

事務的概念源自於資料庫管理系統(DBMS)中資料庫事務的概念。在資料庫管理系統中,事務必須滿足ACID性質,即原子性,一致性,隔離性和持久性。原子性指的是事務中的動作要麼全部執行,要麼一個都不執行;一致性指的是任何時刻,資料庫必須處於一致性狀態,即必須滿足某些預先設定的條件;隔離性是指一個事務不能看見其他未提交事務所涉及到的內部對象的狀態,而持久性則是指一個已提交的事務對資料庫系統的改變必須是永久的。由於STM中的資料是全都放在記憶體而不是資料庫或檔案系統裡的,所以STM只提供了事務的前三個屬性,而缺少了對持久性的支援。通過將對記憶體的訪問封裝在事務(transactions)中,STM消除了多線程記憶體同步過程中我們易犯的那些錯誤!

在Clojure語言中,STM實現採用了與資料庫相似的多版本並發控制技術(MVCC),其並發控制也和資料庫中的樂觀鎖(optimistic locking)很像。當我們啟動一個事務的時候,STM會記錄一下時間戳記,並將事務中將會用到所有ref都拷貝一份。由於狀態是不可變的,所以對於ref的拷貝是多快好省的。當對某個不可變狀態進行“變更”的時候,我們其實並沒有改變它的值(value),而是為其建立了一個含有新值的拷貝。該拷貝是本事務的一個內部狀態,並且由於我們使用了持久化的資料結構,這一步也是多快好省的。而如果STM識別出我們操作過的ref已經被別的事務改了的話,它就會中止並重做本事務。當事務成功完成時,所有的變更都會被寫入記憶體,而時間戳記也將被更新!

 STM中的事務實現

軟體事務記憶體的實現包括原子物件(Atomic object)、衝突判決器(Conflict manager)。其中原子物件的實現是最重要的,它是各事務之間通訊同步的媒介。原子物件的實現又分為順序性實現和事務實現:其中事務實現還要要求實現同步和恢複(recovery)功能,同步功能即意味著要求有檢測事務衝突的能力,而恢複功能則意味著需要在事務失敗的時候將對象復原到事務執行之前的狀態。目前提出的原子物件一般是基於讀/寫衝突(Read/Write conflict)的機制:原子物件提供兩個介面,一個為讀介面,一個為寫介面,通過讀介面可以得到一個可以讀的對象,而通過寫介面則可以得到一個可以寫的對象。為了檢測衝突(即多個事務並發時的同步情況),事務中可以設立兩個集合,一個為讀集(Read set),一個為寫集(Write set),分別記錄該事務所要處理的讀寫原子物件集。如果一個事務的讀集或寫集與另一個事務的寫集有交叉,則表明兩個事務衝突,需要衝突判決器進一步採取決策。

總結:STM 軟體事務記憶體——本質是為提高並發,通過事務來管理記憶體的讀寫訪問以避免鎖的使用!對於clojure,akka來說,只需將對事務記憶體的操作封裝為事務,簡化了並發編程而讓程式員無需考慮複雜的事務同步問題!

STM 軟體事務記憶體——本質是為提高並發,通過事務來管理記憶體的讀寫訪問以避免鎖的使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.