線程問題----線程爭用(加鎖)

若是在線程之間共享數據,則可能會出現線程爭用的問題c#

1,局一個線程爭用的例子:安全

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            SampleTask st = new SampleTask();
            StateObject so = new StateObject();
            //開啓20個任務,每一個任務循環執行StateObject類的ChangeState方法
            for (int i = 0; i < 20; i++)
            {
                new Task(st.RaceCondition, so).Start();
            }
            Console.WriteLine("運行完成");
            Console.ReadLine();
        }
    }
    //簡單的任務類
    class SampleTask
    {
        public void RaceCondition(object o)
        {
            Trace.Assert(o is StateObject, "只能傳遞StateObject對象");
            StateObject s = o as StateObject;
            int i = 0;
            //單個任務循環執行StateObject類的ChangeState方法
            while (true)
            {
                s.ChangeState(++i);
            }
        }
    }
    //狀態類
    //若是state爲5,則加1,後面跟着檢查state,若是不爲6,就出現了爭用。
    class StateObject
    {
        int state = 5;
        public void ChangeState(int loop)
        {
            if (state == 5)
            {
                state++;
                //爲false說明出現爭用,則程序斷言(彈出框)
                Trace.Assert(state == 6, "在循環了" + loop.ToString() + "次後出現了爭用");
            }
            state = 5;
        }
    }
   
}

 

 wKiom1TJD3jBFWHWAAQ7_d0U17U441.jpg

 

2,解決辦法:ide

①:使用lock鎖定共享的s變量oop

    //簡單的任務類
    class SampleTask
    {
        public void RaceCondition(object o)
        {
            Trace.Assert(o is StateObject, "只能傳遞StateObject對象");
            StateObject s = o as StateObject;
            
            int i = 0;
            //單個任務循環執行StateObject類的ChangeState方法
            while (true)
            {
                //使用lock鎖定共享的s變量
                lock (s)
                {
                    s.ChangeState(++i);
                }
            }
        }
    }

 ②:將共享對象設置爲線程安全的對象this

    //狀態類
    //若是state爲5,則加1,後面跟着檢查state,若是不爲6,就出現了爭用。
    class StateObject
    {
        int state = 5;
        public void ChangeState(int loop)
        {
            //將共享對象設置爲線程安全的對象
            lock (this)
            {
                if (state == 5)
                {
                    state++;
                    //爲false說明出現爭用,則程序斷言(彈出框)
                    Trace.Assert(state == 6, "在循環了" + loop.ToString() + "次後出現了爭用");
                }
                state = 5;
            }
        }
    }
相關文章
相關標籤/搜索