(本文作者溫少,首發于博客園,轉載請注明)

          非阻塞算法的關鍵思想就是CAS,CAS是compare and set的縮寫,也常被稱為lock-free或者wait-free,通過把compare和set兩個操作原子化,使得不需要使用鎖,但是能夠解決并發 中的資源爭用問題。由于CAS常常是一個回退算法+死循環,所以又被稱為spin-lock。由于CAS沒有使用鎖,線程持續執行,又稱為非阻塞算法 (non-blocking)。術語不統一,但是都差不多表示同一個東西,我都列在這里,方便大家理解。

          CAS通常并發性能會更好,原因有二:
          1、CAS由硬件提供指令支持
          2、整個思路屬于樂觀鎖定,而不同于其他類型的鎖所采用的悲觀鎖定,大多數并發程序,沖突發生時間較少,所以樂觀鎖定更高效。

          非 阻塞算法是當前的一個研究熱點,也越來流行。其顯著的優勢在于避免了鎖帶來的問題,而其主要缺點在于與等價的有鎖算法比較而言,非阻塞算法的實現要復雜一 些。在Java中,doug lea為我們帶來util.concurrent包,CAS在整個并發框架中深入應用,不單提高了效率(atomic),而且提高了接口可用性(例如 CurrentMap的putIfAbsent)。

          有人說,CAS這種技術底層框架提供,不需要了解,其實不然,CAS思想可以應用任何地方,包括數據結構、服務接口、數據庫應用等等。我這篇文章要講的內容就是在關系數據庫應用中使用CAS思想。

          閑話少說,言歸正傳!

          關 系數據庫數據庫提供了"update T set FState = xx where FState = xx",執行這樣的SQL,會返回一個更新行數,在jdbc或者odbc或者ADO .NET中都可以獲得更新行數。上面的SQL,如果更新行數>0,則是更新成功,否則是沒有進行任何更新,這是很典型的CAS??梢哉f,關系數據庫 原生支持CAS。

          例如,現在有一個表:
          Create Table T_COUNTER (FName VARCHAR, FCOUNT INT)

          這個表存儲一些計數器,程序需要對其中的一個計數器進行increment的操作,實現如下:
          // incremnt的實現算法在這個方法里
          public int getAndIncrement(String name) {
              
          for (;;) {
                  
          int expectValue = getCurrentValue((name);
                  
          int updateValue = expectValue + 1;
                  
          if (updateCounter(name, expectValue, updateValue)) return expectValue;
              }
          }

          public boolean updateCounter(String name, int expectValue, int updateValue) {
              String sql 
          = "UPDATE T_COUNTER SET FCOUNT = @updateValue WHERE FName = @name AND FCOUNT = @expectValue";
              
          int updateCount = executeUpdate(sql);
              
          return updateCount > 0;
          }

          public int getCurrentValue((String name) {
              
          // SELECT FCOUNT FROM T_COUNTER WHERE FNAME = @name
              
          // TODO 執行這段SQL,返回FCOUNT的值
              return 0;
          }

          private int executeUpdate(String sql) {
              // TODO 執行SQL,返回更新行數
              return 0;
          }


          這 樣的實現,避免SQL Server中使用locking hints,Oracle、DB2、MySQL中使用select for update長時間鎖定T_COUNTER表,性能更好,也更通用。要知道使用locking hints,不同廠商的數據庫的實現是不一樣的,Oracle和Microsoft SQL Server就相差很大。

          這樣做的優點:
          1、性能更好
          2、鎖表時間更短
          3、基于標準SQL,不同的關系數據庫通用
          4、上述實現并不復雜

          (本文作者溫少,首發于博客園,轉載請注明)
          posted on 2007-11-13 06:33 溫少的日志 閱讀(1464) 評論(4)  編輯  收藏
          Comments
          • # re: 非阻塞算法思想在關系數據庫應用程序開發中的使用
            liigo
            Posted @ 2007-11-13 13:59
            for (;;) {
            int expectValue = getCurrentValue((name);
            int updateValue = expectValue + 1;
            if (updateCounter(name, expectValue, updateValue)) break;
            }

            以上代碼中,如果有其它線程在getCurrentValue()之后修改了計數值(FCOUNT),則期望值(expectValue)永遠不滿足,updateCounter()總是返回假,死循環了……

            不知道理解的對不對,請指正  回復  更多評論   
          • # re: 非阻塞算法思想在關系數據庫應用程序開發中的使用
            sitinspring
            Posted @ 2007-11-13 19:08
            留個記號先.  回復  更多評論   
          • # re: 非阻塞算法思想在關系數據庫應用程序開發中的使用
            溫少的日志
            Posted @ 2007-11-13 21:34
            @liigo,我改了一下示例代碼,不過意思還一樣的。
            回答你的問題,通常都是執行一次就會退出循環了  回復  更多評論   
          • # re: 非阻塞算法思想在關系數據庫應用程序開發中的使用
            wd
            Posted @ 2007-11-14 12:56
            這不就是hibernate中樂觀鎖的實現嗎?

            很好的文章,終于搞清楚CAS是什么意思了,多謝多謝哦:)  回復  更多評論   

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
           
          主站蜘蛛池模板: 辉南县| 高邑县| 贵州省| 宜宾县| 长沙县| 临夏县| 如皋市| 巴马| 阿城市| 郎溪县| 屯昌县| 苗栗市| 外汇| 横山县| 金塔县| 阳原县| 五原县| 山东| 轮台县| 西充县| 巩义市| 武义县| 文安县| 南丹县| 庐江县| 时尚| 嘉祥县| 府谷县| 静乐县| 怀集县| 和龙市| 砚山县| 右玉县| 庆元县| 石首市| 乐至县| 祁连县| 斗六市| 静宁县| 报价| 平利县|