天天看點

多線程什麼時候該加鎖?

1 .加鎖、解鎖(同步/互斥)是多線程中非常基本的操作,但我卻看到不少的代碼對它們處理的很不好。簡單說來有三類問題,一是加鎖範圍太大,雖然避免了邏輯錯誤,但鎖了不該鎖的東西,難免降低程式的效率;二是該鎖的不鎖,導緻各種莫名其妙的錯誤;三是加鎖方式不合适,該用臨界區的用核心對象等,也會降低程式的效率。

要正确的運用鎖操作,首先要弄清楚什麼時候需要加鎖。一般可能“同時發生多個寫操作”或“同時發生讀寫操作”時,必需要加Lock.

此類問題也不光會出現在匿名方法中。如果您使用Lambda表達式建立了一個表達式樹,其中也用到了一個“局部變量”,那麼表達式樹在解析或執行時同樣也會擷取“目前”的值,而不是建立表達式樹時的值。

即:Linq中使用List.AsParallel()

 //賬單所包含的訂單總重。此時會導緻未知的錯誤!!

可能同一時間有線程A在傳回Weigh(讀),另一線程B進行Sum計算;産生多線程同時讀寫操作。 

decimal orderTotalWeight = order7.AsParallel().Sum(m => bllOrderInfo.GetProductCodeWeight(m.Code) * m.Quantity).ToDecimal();

       /// <summary>

        /// 根據産品編号擷取重量。

        /// </summary>

        /// <param name="productCode"></param>

        /// <returns></returns>

        public decimal GetProductCodeWeight(string productCode)

        {

                . .. . .

               ...........

               return result;

        }

共享資料個人了解的是全局變量,多個線程同時通路全局變量會導緻不可預知的錯誤!

例如:

private int m_Count;

public void  Calc()

{

    int count;

    count++;

    lock()

    {

       m_Count++;

    }

}

繼續閱讀