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

          非阻塞算法的關鍵思想就是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。可以說,關系數據庫 原生支持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是什么意思了,多謝多謝哦:)  回復  更多評論   

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


          網站導航:
           
           
          主站蜘蛛池模板: 邵阳市| 棋牌| 遵化市| 闽侯县| 乐陵市| 敦化市| 永和县| 烟台市| 思茅市| 温宿县| 于田县| 岫岩| 北宁市| 南和县| 黄浦区| 西盟| 青铜峡市| 贵南县| 株洲县| 灌云县| 衡水市| 铜梁县| 额尔古纳市| 五常市| 彝良县| 喀喇沁旗| 曲水县| 宝应县| 洪江市| 甘泉县| 安新县| 黄石市| 新龙县| 广河县| 将乐县| 高邮市| 呼伦贝尔市| 兴宁市| 仙桃市| 屏南县| 大宁县|