亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入多線程之:深入分析Interlocked

 更新時間:2013年05月14日 15:26:23   作者:  
本篇文章是對Interlocked進行了詳細的分析介紹,需要的朋友參考下

在大多數(shù)計算機上,增加變量操作不是一個原子操作,需要執(zhí)行下列步驟:

       一:將實例變量中的值加載到寄存器中。

       二:增加或減少該值。

       三:在實例變量中存儲該值。

在多線程環(huán)境下,線程會在執(zhí)行完前兩個步驟后被搶先。然后由另一個線程執(zhí)行所有三個步驟,當?shù)谝粋€線程重新開始執(zhí)行時,它覆蓋實例變量中的值,造成第二個線程執(zhí)行增減操作的結果丟失。

Interlocked可以為多個線程共享的變量提供原子操作。

    Interlocked.Increment:以原子操作的形式遞增指定變量的值并存儲結果。
    Interlocked.Decrement以原子操作的形式遞減指定變量的值并存儲結果。
    Interlocked.Add以原子操作的形式,添加兩個整數(shù)并用兩者的和替換第一個整數(shù)

但是Interlocked并沒有為乘法,除法提供原子操作。那么如何實現(xiàn)乘法,除法,以及為其他的一些非原子操作提供原子操作的支持呢??


關鍵就在于Interlocked.CompareExchange 中,Jeffrey Richter把它叫做InterLocked Anything 模式。

下面我們使用Interlocked.CompareExchange 實現(xiàn)求最大值的原子操作。

復制代碼 代碼如下:

public static int Maximum(ref int target, int value)
        {
            int currentVal = target;   //將target的當前值保存到currentVal中
            int startVal, desiredVal;  //聲明兩個變量來記錄操作開始前的值和期望的結果值。

            do
            {
                startVal = currentVal; //將currentVal中的值保存到startVal中,此時記錄的是target在操作開始前的最初值。
                desiredVal = Math.Max(startVal, value); //通過startVal進行復雜的計算,返回一個期望的結果,在這里僅僅是返回兩者的最大值。

                //線程可能在這里被搶占,target的值可能被改變
                //如果target的值被改變了,那么target和startVal的值就不想等,所以就不應該用desiredVal替換target.
                //如果target的值沒有被改變,那么target和startVal的值就像等,使用desiredVal替換target.
                //不管替換或者不替換,CompareExchange的返回值始終是target的值,所以currentVal的值現(xiàn)在是target的最新值。

                //CompareExchange:將target和startVal的值比較,相等則用desiredVal替換,否則不操作,
                //不管替換還是不替換返回的都是原來保存在target的值。
                currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);
            } while (startVal != currentVal); //當target的起始值和最新值不相等的時候,說明target被修改了,所以繼續(xù)下次判斷,否則退出循環(huán)。
            return desiredVal;
        }


這段代碼的核心就是:currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);
// 將target的值和startVal的值比較,相等則用desiredVal替換target,否則不操作,
//不管替換還是不替換返回的都是原來保存在target的值。

在這里,計算可能會比較復雜,而不像上面的Math.Max一樣,所以可以使用委托調(diào)用的方式進行封裝。

復制代碼 代碼如下:

delegate int Morpher<TResult, TArgument>(int startValue, TArgument argument,
            out TResult morphResult);

        static TResult Morph<TResult, TArgument>(ref int target, TArgument argument,
            Morpher<TResult, TArgument> morpher)
        {
            TResult morphResult;

            int currentVal = target, startVal, desiredVal;

            do
            {
                startVal = currentVal;
                desiredVal = morpher(startVal, argument, out morphResult);
                currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);
            } while (startVal != currentVal);

            return morphResult;
        }


基本原理和上面的一致。

相關文章

  • C# 位運算符整理

    C# 位運算符整理

    在C#中可以對整型運算對象按位進行邏輯運算。按位進行邏輯運算的意義是:依次取被運算對象的每個位,進行邏輯運算,每個位的邏輯運算結果是結果值的每個位。
    2008-10-10
  • C#解析json字符串總是多出雙引號的原因分析及解決辦法

    C#解析json字符串總是多出雙引號的原因分析及解決辦法

    json好久沒用了,今天在用到json的時候,發(fā)現(xiàn)對字符串做解析的時候總是多出雙引號,下面給大家介紹C#解析json字符串總是多出雙引號的原因分析及解決辦法,需要的朋友參考下吧
    2016-03-03
  • C# 修改文件的創(chuàng)建、修改和訪問時間的示例

    C# 修改文件的創(chuàng)建、修改和訪問時間的示例

    這篇文章主要介紹了C#實現(xiàn)修改文件的創(chuàng)建、修改和訪問時間的示例,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下
    2021-04-04
  • c#基礎系列之值類型和引用類型的深入理解

    c#基礎系列之值類型和引用類型的深入理解

    這篇文章主要給大家介紹了關于c#基礎系列之值類型和引用類型的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-09-09
  • Unity3D運行報DllNotFoundException錯誤的解決方案

    Unity3D運行報DllNotFoundException錯誤的解決方案

    這篇文章主要介紹了Unity3D運行報DllNotFoundException錯誤的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • C# this關鍵字的四種用法

    C# this關鍵字的四種用法

    這篇文章主要為大家詳細介紹了C# this關鍵字的四種用法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 淺析C#更改令牌ChangeToken

    淺析C#更改令牌ChangeToken

    這篇文章主要介紹了C#更改令牌ChangeToken,文中運用大量代碼講解的非常詳細,感興趣的小伙伴一起來看看這篇文章吧
    2021-09-09
  • C#驗證身份證號碼正確性的實例代碼(收藏)

    C#驗證身份證號碼正確性的實例代碼(收藏)

    這篇文章主要介紹了C#驗證身份證號碼正確性的實例代碼,包括18位號碼和15位號碼的校驗,需要的朋友可以參考下
    2017-07-07
  • C# 使用CancellationTokenSource取消多線程

    C# 使用CancellationTokenSource取消多線程

    有時間我們在使用多線程的時候,需要取消線程的執(zhí)行,可以使用CancellationTokenSource來取消對Task開辟多線程的取消,感興趣的可以了解一下
    2021-08-08
  • c#與WMI使用技巧集

    c#與WMI使用技巧集

    c#與WMI使用技巧集...
    2007-03-03

最新評論