csharp 集合的并发,避免使用传统的锁(lock)机制等方式来处理并发访问集合。因此当有多个线程并发访问集合时,应首先考虑使用这些类代替System.Collections和System.Coll

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 集合的并发,避免使用传统的锁(lock)机制等方式来处理并发访问集合。因此当有多个线程并发访问集合时,应首先考虑使用这些类代替System.Collections和System.Coll相关的知识,希望对你有一定的参考价值。

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication8
{
    class ConcurrentBagProgram
    {
        static void Main(string[] args)
        {
            //表示实现的是一个无序的集合类
            //该类有两个重要的方法用来访问队列中的元素.分别是:
            //TryTake 尝试移除并返回位于队列头开始处的对象.
            //TryPeek尝试返回位于队列头开始处的对象但不将其移除.
            ConcurrentBag<int> sharedBag = new ConcurrentBag<int>();
            for (int i = 0; i < 1000; i++)
            {
                sharedBag.Add(i);
            }
            int itemCount = 0;
            Task[] tasks = new Task[10];
            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = new Task(() =>
                {
                    while (sharedBag.Count > 0)
                    {
                        int queueElement;
                        bool gotElement = sharedBag.TryTake(out queueElement);
                        if (gotElement)
                            Interlocked.Increment(ref itemCount);
                    }
                });
                tasks[i].Start();
            }
            Task.WaitAll(tasks);
            Console.WriteLine("Items processed:{0}", itemCount);
            Console.WriteLine("Press Enter to finish");
            Console.WriteLine(itemCount);
            Console.ReadLine();
        }
    }
}
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication8
{
    class ConcurrentQueueProgram
    {
        static void Main(string[] args)
        {
            //表示线程安全的先进先出(FIFO)队列
            //TryDequeue 尝试移除并返回位于队列头开始处的对象.
            //TryPeek尝试返回位于队列头开始处的对象但不将其移除.
            ConcurrentQueue<int> sharedQueue = new ConcurrentQueue<int>();
            for (int i = 0; i < 1000000; i++)
            {
                sharedQueue.Enqueue(i);
            }
            int itemCount = 0;
            Task[] tasks = new Task[10];
            for (int i = 0; i < tasks.Length; i++)
            {
                tasks[i] = new Task(() =>
                {
                    while (sharedQueue.Count > 0)
                    {
                        int queueElement;
                        bool gotElement = sharedQueue.TryDequeue(out queueElement);
                        if (gotElement)
                        {
                            Interlocked.Increment(ref itemCount);
                        }
                    }
                });
                tasks[i].Start();
            }
            Task.WaitAll(tasks);
            Console.WriteLine("Items processed:{0}", itemCount);
            Console.WriteLine("Press Enter to finish");
            Console.WriteLine(itemCount);
            Console.ReadLine();
        }
    }
}
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication8
{
  // 集合的并发,避免使用传统的锁(lock)机制等方式来处理并发访问集合.因此当有多个线程并发访问集合时,应首先考虑使用这些类代替 System.Collections 和 System.Collections.Generic 命名空间中的对应类型
    class BankAccount
    {
        public int Balance
        {
            get;
            set;
        }
    }
    class ConcurrentBagProgram
    {
        static void Main(string[] args)
        {
            //实现的是一个键 - 值集合类.它提供的方法有:
            //TryAdd:尝试向集合添加一个键 - 值
            //TryGetValue:尝试返回指定键的值.
            //TryRemove:尝试移除指定键处的元素.
            //TryUpdate:尝试更新指定键的值.
            BankAccount account = new BankAccount();
            ConcurrentDictionary<object, int> sharedDict = new ConcurrentDictionary<object, int>();
            Task<int>[] tasks = new Task<int>[10];
            for (int i = 0; i < tasks.Length; i++)
            {
                sharedDict.TryAdd(i, account.Balance);
                tasks[i] = new Task<int>((keyObj) =>
                {
                    int currentValue;
                    bool gotValue;
                    for (int j = 0; j < 1000; j++)
                    {
                        gotValue = sharedDict.TryGetValue(keyObj, out currentValue);
                        sharedDict.TryUpdate(keyObj, currentValue + 1, currentValue);
                    }
                    int result;
                    gotValue = sharedDict.TryGetValue(keyObj, out result);
                    if (gotValue)
                    {
                        return result;
                    }
                    else
                    {
                        throw new Exception(String.Format("No data item available for key {0}", keyObj));
                    }
                }, i);
                tasks[i].Start();
            }
            for(int i = 0; i < tasks.Length; i++)
            {
                account.Balance += tasks[i].Result;
            }
            Console.WriteLine("Expected value {0}, Balance: {1}", 10000, account.Balance);
            Console.WriteLine("Press enter to finish");
            Console.WriteLine(account.Balance);
            Console.ReadLine();
        }
    }
}

以上是关于csharp 集合的并发,避免使用传统的锁(lock)机制等方式来处理并发访问集合。因此当有多个线程并发访问集合时,应首先考虑使用这些类代替System.Collections和System.Coll的主要内容,如果未能解决你的问题,请参考以下文章

深入剖析 HIVE 的锁和事务机制

深入剖析 HIVE 的锁和事务机制

mysql中的锁机制之概念篇

Mysql中的锁机制

Mysql中的锁机制详解

学习笔记Java中的锁Lock