C# ConcurrentQueue 處理多任務

 

一,集合之線程同步

即位於System.Collections命名空間下的集合,如Hashtable,ArrayList,Stack,Queue等.其均提供了線程同步的一個實現

每種數據類型都包含一個靜態的Synchronized方法,如

方法1,

併發讀一個寫。如果有多個線程併發的企圖寫list裏面的 item, 則同一時刻只能有一個線程寫, 其餘阻塞; 對讀的線程則不受影響。

ArrayList list = ArrayList.Synchronized(new ArrayList(1000000));

方法2,自己加控制鎖
public class Demo8
{
    ArrayList list = new ArrayList(1000000);
    public Demo8()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(Task1));
        ThreadPool.QueueUserWorkItem(new WaitCallback(Task2));
    }

    public void Task1(object obj)
    {
        lock (list.SyncRoot)
        {
            for (int i = 0; i < 500000; i++)
            {
                list.Add(i);
            }
        } 
       
        Console.WriteLine(DateTime.Now);
        Console.WriteLine("Task1 count {0}", list.Count);
    }

    public void Task2(object obj)
    {
        lock (list.SyncRoot)
        {
            for (int i = 0; i < 500000; i++)
            {
                list.Add(i);
            }
        }
        Console.WriteLine("Task2 count {0}", list.Count);
    }
}

二,ConcurrentQueue .Net自帶的支持多線程隊列

/// <summary>
/// 多線程處理數據(無返回值)
/// </summary>
/// <typeparam name="T">數據類型</typeparam>
/// <param name="list">待處理數據</param>
/// <param name="action">數據處理方法(有參數無返回值)</param>
/// <param name="count">處理線程數量</param>
/// <param name="waitFlag">是否等待執行結束</param>
static void RunTask<T>(List<T> list, Action<T> action, int threadCount = 5, bool waitFlag = true)
{
<T> queue = new ConcurrentQueue<T>(list);
Task[] tasks = new Task[threadCount];
for (int i = 0; i < threadCount; i++)
{
tasks[i] = Task.Run(() =>
{
while (queue.TryDequeue(out T t))
{
action(t);
}
});
}
if (waitFlag)
{
Task.WaitAll(tasks);
}
}

/// <summary>
/// 多線程處理數據(返回處理後列表)
/// </summary>
/// <typeparam name="T">數據類型</typeparam>
/// <param name="list">待處理數據</param>
/// <param name="func">數據處理方法(有參數有返回值)</param>
/// <param name="threadCount">處理線程數量</param>
/// <returns>數據處理後結果</returns>
static List<T> RunTask<T>(List<T> list, Func<T, T> func, int threadCount = 5)
{
var result = new List<T>();
ConcurrentQueue<T> queue = new ConcurrentQueue<T>(list);
Task<List<T>>[] tasks = new Task<List<T>>[threadCount];
for (int i = 0; i < threadCount; i++)
{
tasks[i] = Task.Run<List<T>>(() =>
{
var rList = new List<T>();
while (queue.TryDequeue(out T t))
{
rList.Add(func(t));
}
return rList;
});
}
Task.WaitAll(tasks);
for (int i = 0; i < threadCount; i++)
{
result.AddRange(tasks[i].Result);
}
return result;
}

 

//----------------------Test-----------------

List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
//輸出列表中的數據,且加上“action”字符前綴
RunTask<int>(list, d => { Console.WriteLine("action" + d); });

//對列表中數據都執行 “*2” 的操作
var result = RunTask<int>(list, d => { return d * 2; });
result.ForEach(d => Console.WriteLine(d));

 

效率提示的題外總結:

HashTable中的key/value均爲object類型,由包含集合元素的存儲桶組成。存儲桶是 HashTable中各元素的虛擬子組,與大多數集合中進行的搜索和檢索相比,存儲桶可令搜索和檢索更爲便捷。每一存儲桶都與一個哈希代碼關聯,該哈希代碼是使用哈希函數生成的並基於該元素的鍵。HashTable的優點就在於其索引的方式,速度非常快。如果以任意類型鍵值訪問其中元素會快於其他集合,特別是當數據量特別大的時候,效率差別尤其大。
HashTable的應用場合有:做對象緩存,樹遞歸算法的替代,和各種需提升效率的場合。
Hashtable 與Dictionary 區別
1,HashTable是經過優化的,訪問下標的對象先散列過,所以內部是無序散列的,保證了高效率,也就是說,其輸出不是按照開始加入的順序,而Dictionary遍歷輸出的順序,就是加入的順序,這點與Hashtable不同
2,HashTable 不用 裝箱。
System.Collections.Hashtable ht = new System.Collections.Hashtable();
ht.Add(1, "apple");

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章