程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 【Java並發編程】2、無鎖編程:lock-free原理;CAS;ABA問題

【Java並發編程】2、無鎖編程:lock-free原理;CAS;ABA問題

編輯:關於JAVA

【Java並發編程】2、無鎖編程:lock-free原理;CAS;ABA問題。本站提示廣大學習愛好者:(【Java並發編程】2、無鎖編程:lock-free原理;CAS;ABA問題)文章只能為提供參考,不一定能成為您想要的結果。以下是【Java並發編程】2、無鎖編程:lock-free原理;CAS;ABA問題正文


轉自:http://blog.csdn.net/kangroger/article/details/47867269

定義

無鎖編程是指在不使用鎖的情況下,在多線程環境下實現多變量的同步。即在沒有線程阻塞的情況下實現同步。這樣可以避免競態、死鎖等問題。

原理

CAS是指Compare-and-swap或Compare-and-Set 
CAS是一個原子操作,用於多線程環境下的同步。它比較內存中的內容和給定的值,只有當兩者相同時(說明其未被修改),才會修改內存中的內容。 
實現如下:

int compare_and_swap(int* reg, int oldval, int newval)
{
  ATOMIC();
  int old_reg_val = *reg;
  if (old_reg_val == oldval)
     *reg = newval;
  END_ATOMIC();
  return old_reg_val;
}

bool compare_and_swap(int *accum, int *dest, int newval)
{
  if (*accum == *dest) {
      *dest = newval;
      return true;
  } else {
      *accum = *dest;
      return false;
  }
}

返回bool值得好處是可以知道是否設置成功。

在實際環境中,使用的是:

bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)
type __sync_val_compare_and_swap (type *ptr, type oldval, type newval, ...)

在使用CAS時,需要先獲取操作變量的值並放到oldval中,之後調用cas函數,直到調用成功。例如給變量val賦值

while(true)
{
    int oldval=val;
    if(__sync_bool_compare_and_swap(&val, oldval, newval))
        break;
}
ABA問題

在多線程環境中,使用lock-free的CAS時,如果一個線程對變量修改2次,第2次修改後的值和第1次修改前的值相同,那麼可能就會出現ABA問題。以上面的例子為例: 
假設有兩個線程P1和P2,P1執行完int oldval=val後被其他線程搶占。P2線程在此期間修改了val的值(可能多次修改),但最終val的值和修改前一樣。當P1線程之後運行CAS函數時,並不能發現這個問題。這就是ABA問題。

解決方法

一個常用的方法是添加額外的“tag”或“stamp”位來標記是指針是否被修改過。

參考: 
Compare-and-swap

ABA problem

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved