多個 Thread 共用變數 多個 Thread 共用變數
  .NET       ez      2012-06-04

當使用多個Thread,共用一個變數進行加總,為什麼總合會不同? 範例程式碼:

using System;
using System.Collections.Generic;
using System.Threading;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            int count = 0;
            List<Thread> List_Thread = new List<Thread>();
            for (int i = 0; i < 10; i++)
            {
                //建立執行緒
                List_Thread.Add(new Thread(() =>
                {
                    int temp = 10000;
                    while (temp-- > 0) count++;
                }));
                List_Thread[i].Start();
            }
            //等待所有執行緒完成
            foreach (Thread t in List_Thread) t.Join();
            Console.WriteLine(count.ToString());
            Console.ReadLine();
        }
    }
}

結果畫面:

這是因為共用變數造成資料碰撞,所以同時多個 Thread 對變數進行加總,雖然各加了一次但只會+1 解決方式是使用lock,當要進入加總前,先進行lock的動作,等加總完畢後才允許另外一個Thread進入加總。

using System;
using System.Collections.Generic;
using System.Threading;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            object _lock = new object(); //建立一個object給lock使用
            int count = 0;
            List<Thread> List_Thread = new List<Thread>();
            for (int i = 0; i < 100; i++)
            {
                //建立執行緒
                List_Thread.Add(new Thread(() =>
                {
                    int temp = 10000;
                    while (temp-- > 0)
                    {
                        lock (_lock) count++; //加入Lock
                    }
                }));
                List_Thread[i].Start();
            }
            //等待所有執行緒完成
            foreach (Thread t in List_Thread) t.Join();
            Console.WriteLine(count.ToString());
            Console.ReadLine();
        }
    }
}

另外方式使用System.Monitor,也可以達到相同效果,並且功能更多!

using System;
using System.Collections.Generic;
using System.Threading;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            object _lock = new object(); //建立一個object給lock使用
            int count = 0;
            List<Thread> List_Thread = new List<Thread>();
            for (int i = 0; i < 100; i++)
            {
                //建立執行緒
                List_Thread.Add(new Thread(() =>
                {
                    int temp = 10000;
                    while (temp-- > 0)
                    {
                        Monitor.Enter(_lock); //開始Lock
                        count++;
                        Monitor.Exit(_lock); //結束Lock
                    }
                }));
                List_Thread[i].Start();
            }
            //等待所有執行緒完成
            foreach (Thread t in List_Thread) t.Join();
            Console.WriteLine(count.ToString());
            Console.ReadLine();
        }
    }
}

標籤:   .NET

我要留言