.net 4.0 中對多執行緒新特性(轉)

iDotNetSpace發表於2010-08-12

在4.0之前如果需要在多執行緒環境下操作集合型別的物件往往需要額為每種操作新增比較複雜的鎖機制才能保證每個執行緒對資源的訪問安全,在4.0的Collection名稱空間下面又多了一個新的名稱空間Concurrent,在這個名稱空間下面增加了幾個非常有用的執行緒安全的類:
BlockingCollection                    為實現 IProducerConsumerCollection)>) 的執行緒安全集合提供阻止和限制功能。
ConcurrentBag                        表示物件的執行緒安全的無序集合。
ConcurrentDictionary    表示可由多個執行緒同時訪問的鍵值對的執行緒安全集合。
ConcurrentQueue                    表示執行緒安全的先進先出 (FIFO) 集合。
ConcurrentStack                     表示執行緒安全的後進先出 (LIFO) 集合。
OrderablePartitioner                 表示將一個可排序資料來源拆分成多個分割槽的特定方式。
Partitioner                                     提供針對陣列、列表和可列舉項的常見分割槽策略。
Partitioner                               表示將一個資料來源拆分成多個分割槽的特定方式。

通一個簡單的例子可以非常容易的來應用這些特性

.net 4.0 中對多執行緒新特性(轉)class Program
    {
        static ConcurrentDictionary<int, int> dict = new ConcurrentDictionary<int, int>();

        static void Main(string[] args)
        {
            for (int i = 0; i < 5; i++)
            {
                var thread = new Thread(new ThreadStart(Action));
                thread.Start();
            }

            Console.Read();
        }

        static void Action()
        {
            var rd = new Random();
            for (int i = 0; i < 10; i++)
            {
                Thread.Sleep(rd.Next(1, 5));
                var k = dict.TryAdd(i, i);
                Console.WriteLine("Thread {0} add {1} {2}", Thread.CurrentThread.ManagedThreadId, i, ok ? "success" : "fail");
            }
        }
    }

程式輸出如下:

Thread 11 add 0 success
Thread 11 add 1 success
Thread 12 add 0 fail
Thread 13 add 0 fail
Thread 11 add 2 success
Thread 12 add 1 fail
Thread 14 add 0 fail
Thread 12 add 2 fail
Thread 13 add 1 fail

從輸出結果我們看到在多執行緒競爭的情況下ConcurrentDictionary能夠很好的處理鎖競爭的問題。

生產消費模式在多執行緒中是非常常見的一種模式了,在4.0之前需要一套比較複雜的讀寫鎖來處理處理併發資源競爭的問題,在4.0中藉助BlockingCollection  類可以很容易的實現了。即使一個新手也能夠非常容易的掌握而不需太多去了解多執行緒的細節問題。來個簡單的例子:

.net 4.0 中對多執行緒新特性(轉)static void Main(string[] args)
        {
            TestCase.Test();

            Console.Read();
        }
class TestCase
    {
        static ConcurrentBag _bag = new ConcurrentBag();

        public static void Test()
        {
            var produce = new Thread(new ThreadStart(Produce));
            var consume = new Thread(new ThreadStart(Consume));

            produce.Start();
            consume.Start();
        }

        static void Produce()
        {
            int index = 0;
            while (true)
            {
                if (_bag.IsEmpty)
                {
                    string productName = "Product " + index.ToString();
                    _bag.Add(new Product() { Name = productName });
                    Console.WriteLine("Produce Product {0} ", productName);
                    index += 1;
                }
                Thread.Sleep(1000);
            }
        }

        static void Consume()
        {
            while (true)
            {
                if (!_bag.IsEmpty)
                {
                    Product item;
                    if (_bag.TryTake(out item))
                    {
                        Console.WriteLine("Consume Product {0} " , item.Name);
                    }
                }
                Thread.Sleep(1000);
            }
        }
    }

    class Product
    {
        public string Name { get; set; }
    }

程式輸出如下:

Consume Product Product 0
Produce Product Product 1
Consume Product Product 1
Produce Product Product 2
Consume Product Product 2
Produce Product Product 3
Consume Product Product 3
Produce Product Product 4
Consume Product Product 4


 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-670846/,如需轉載,請註明出處,否則將追究法律責任。

相關文章