常用算法帖(C#): 并发集合

    微软对C#(4.0)的框架添加了全新的并发编程框架,现在我们也能用C#开发支持并发概念的程序的。在并发编程中最让人烦恼的应该就是如何数据同步:避免脏读和脏写,当然我们可以通过Lock技术来实现,也可以使用微软提供给我们的并发集合,这些集合都提供了TryDo方法。用它们对数据的读/写操作能在TryDo返回True的情况下执行。我们来看看它们吧:

 

IProducerConsumerCollection

    所有的并发集合都实现了这个接口,TryAdd和TryTake分别在读和写的时候判断是否能正常进行,不行则返回false。

    public interface IProducerConsumerCollection<T> : IEnumerable<T>, ICollection, IEnumerable

    {

        void CopyTo(T[] array, int index);

        T[] ToArray();

        bool TryAdd(T item);

        bool TryTake(out T item);

    }



 

ConcurrentQueue

    并发队列,队列类型的数据结构。

 public static void ConcurrentQueueTest()

        {

            Parallel.For<Queue<string>>(1, 10000,

                () =>

                {

                    while (strNornalQueue.Count != 26)

                    {

                        if (strNornalQueue.Count == 0)

                        {

                            for (int i = 65; i <= 90; i++)

                            {

                                strNornalQueue.Enqueue(Convert.ToChar(i).ToString());

                            }

                        }



                    }

                    Console.WriteLine("-------------start------------");

                    return strNornalQueue;

                },

                (index, state, head) =>

                {

                    string tmp = string.Empty;

                    tmp = head.Dequeue();

                    Console.WriteLine(string.Format("The element '{0}' was set by thread {1}", tmp, System.Threading.Thread.CurrentThread.ManagedThreadId));

                    head.Enqueue(tmp);

                    

                    return strNornalQueue;

                },

                (result) =>

                {

                    Console.WriteLine("-------------end------------------");

                });

            Console.WriteLine(string.Format("current collection has {0} elements, Has duplicate data:{1}", strNornalQueue.Count, IsDuplicate<string>(strNornalQueue.GetEnumerator())));



            foreach (string item in strNornalQueue)

            {

                Console.WriteLine(item);

            }



        }


 

 

ConcurrentStack

并发栈,栈类型的数据结构。

     public static void ConcurrentStackTest()

        {

            Parallel.For<ConcurrentStack<string>>(1, 10000,

                () =>

                {

                    while (strStack.Count != 26)

                    {

                        if (strStack.Count == 0)

                        {

                            for (int i = 65; i <= 90; i++)

                            {

                                strStack.Push(Convert.ToChar(i).ToString());

                            }

                        }



                    }

                    Console.WriteLine("-------------start------------");

                    return strStack;

                },

                (index, state, head) =>

                {

                    string tmp = string.Empty;

                    if (head.TryPop(out tmp))

                    {

                        Console.WriteLine(string.Format("The element '{0}' was set by thread {1}", tmp, System.Threading.Thread.CurrentThread.ManagedThreadId));

                        head.Push(tmp);

                    }

                    else

                    {

                        Console.WriteLine("queue is buzy now");

                    }

                    return strStack;

                },

                (result) =>

                {

                    Console.WriteLine("-------------end------------------");

                });

            Console.WriteLine(string.Format("current collection has {0} elements, Has duplicate data:{1}", strStack.Count, IsDuplicate<string>(strStack.GetEnumerator())));



            foreach (string item in strStack)

            {

                Console.WriteLine(item);

            }

        }


 

ConcurrentDictionary

    并发字典,字典类型的数据结构。

 public static void ConcurrentDictionary()

        {

            for (int i = 65; i <= 90; i++)

            {

                strDictionary.TryAdd(Convert.ToChar(i).ToString(), Convert.ToChar(i).ToString());

            }



            Parallel.For<ConcurrentDictionary<string,string>>(1, 10000,

               () =>

               {

                  

                   Console.WriteLine("-------------start------------");

                   return strDictionary;

               },

               (index, state, head) =>

               {

                   string tmp = string.Empty;

                   if (head.TryRemove(Convert.ToChar(new Random().Next(65,90)).ToString(), out tmp))

                   {

                       

                       Console.WriteLine(string.Format("The element '{0}' was set by thread {1}", tmp, System.Threading.Thread.CurrentThread.ManagedThreadId));

                       head.TryAdd(tmp, tmp);

                   }

                   else

                   {

                       Console.WriteLine("queue is buzy now");

                   }

                   return strDictionary;

               },

               (result) =>

               {

                   Console.WriteLine("-------------end------------------");

               });

        }


 

ConcurrentBag

    类似堆栈的数据结构。

public static void ConcurrentBag()

        {

            for (int i = 65; i <= 90; i++)

            {

                strBag.Add(Convert.ToChar(i).ToString());

            }

            Parallel.For<ConcurrentBag<string>>(1, 10000,

                () =>

                {



                    return strBag;

                },

                (index, state, head) =>

                {

                    string tmp = string.Empty;

                    if (strBag.TryTake(out tmp))

                    {

                        Console.WriteLine(string.Format("The element '{0}' was set by thread {1}", tmp, System.Threading.Thread.CurrentThread.ManagedThreadId));

                        strBag.Add(tmp);

                    }

                    else

                    {

                        Console.WriteLine("queue is buzy now");

                    }

                   



                    return strBag;

                },

                (result) =>

                {

                    Console.WriteLine("-------------end------------------");

                });

            Console.WriteLine(string.Format("current collection has {0} elements, Has duplicate data:{1}", strBag.Count, IsDuplicate<string>(strBag.GetEnumerator())));



            foreach (string item in strBag)

            {

                Console.WriteLine(item);

            }

        }


 

 

BlockingCollection

    并发集合,在程序操作完之前会一直阻塞其他程序对其进行操作。

 public static void BlockingCollectionTest()

        {

            Parallel.For<BlockingCollection<string>>(1, 10000,

                    () =>

                    {

                        while (strBlockCollection.Count != 26)

                        {

                            if (strBlockCollection.Count == 0)

                            {

                                for (int i = 65; i <= 90; i++)

                                {

                                    strBlockCollection.Add(Convert.ToChar(i).ToString());

                                }

                            }



                        }

                        Console.WriteLine("-------------start------------");

                        return strBlockCollection;

                    },

                    (index, state, head) =>

                    {

                        string tmp = string.Empty;

                        tmp=head.Take();

                        

                        Console.WriteLine(string.Format("The element '{0}' was set by thread {1}", tmp, System.Threading.Thread.CurrentThread.ManagedThreadId));

                        head.Add(tmp);

                        

                        return strBlockCollection;

                    },

                    (result) =>

                    {

                        Console.WriteLine("-------------end------------------");

                    });

            Console.WriteLine(string.Format("current collection has {0} elements, Has duplicate data:{1}", strBlockCollection.Count, IsDuplicate<string>(strBlockCollection.AsEnumerable().GetEnumerator())));



            foreach (string item in strBlockCollection)

            {

                Console.WriteLine(item);

            }

        }



 

 

你可能感兴趣的:(C#)