博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
厚积薄发,丰富的公用类库积累,助你高效进行系统开发(10)---各种线程同步的集合类...
阅读量:5967 次
发布时间:2019-06-19

本文共 16521 字,大约阅读时间需要 55 分钟。

俗话说,一个好汉十个帮,众人拾柴火焰高等都说明一个道理,有更多的资源,更丰富的积累,都是助你走向成功,走向顶峰的推动力。

本篇的公用类库的介绍主题是程序开发中多线程操作环境中,常用到的线程安全的各类同步集合、字典等对象,这些辅助类通过封装及继承关系,获得更加丰富完善的集合类,并且增加了线程锁,实现多线程访问的集合类。本篇随笔介绍包含有有序字典集合、同步字典集合、有序同步字典集合、同步列表、同步先进先出队列等对象。

本篇继续继续整理优化已有的共用类库,并继续发表随笔介绍公用类库的接口方法以及详细使用操作,力求给自己继续优化,积攒更丰富的公用类库资源,加深了解的同时,也给大家展现公用类库好的方面。

 

1、有序的字典集合 OrderedDictionary。  

实现效果

1) 本辅助类主要是用来方便实现有序的字典集合操作。 一个有序的字典是一个集合类,它里面的项目可以通过其索引或他们的键进行操作。。

2) 有序集合对象,特点是查找非常高效率,并且提供了强类型的数据操作,不过由于其需要额外在列表中存储数据,因此尽量减少插入或者删除集合对象。
3) 有序的字典集合,虽然存在一些缺点,但是提供了一个非常灵活和用户友好数据结构,允许通过键值或索引进行访问。

实现代码

1)辅助类提供的方法接口如下所示: 

///     /// 判断字典
是否包含指定的值。 ///
/// 待判断的值,如果值为引用类型,则可以为null ///
/// 如果字典包含项目,则返回true,否则为false。 ///
public virtual bool ContainsValue(TValue value) /// /// 判断字典是否包含指定键的元素 /// /// 在字典中查找的键. ///
/// 如果字典中包含指定键的元素,返回true,否则为false ///
///
键为空
public virtual bool ContainsKey(TKey key) /// /// 在字典中添加一个元素,根据提供的键和值 /// /// 作为待添加元素的键 /// 作为待添加元素的值. ///
字典对象为只读
///
含有相同键的元素已经存在字典中
///
键为空.
public virtual void Add(TKey key, TValue value) /// /// 在指定的索引插入元素 /// /// 插入位置,从零开始的索引 /// 作为待插入元素的键 /// 作为待插入元素的值 ///
集合为只读
///
指定索引在
中为无效索引.
public void Insert(int index, TKey key, TValue value) /// /// 获取指定键的元素索引 /// /// 待查找的键 ///
/// 如果列表中发现则为项目的索引,否则为-1。 ///
public int IndexOf(TKey key) /// /// 获取指定键的元素索引 /// /// 待查找的键 ///
/// 如果列表中发现则为项目的索引,否则为-1。 ///
public int IndexOf(TValue value) /// /// 获取或设置与指定键的值。 /// public virtual TValue this[TKey key] /// 获取或设置指定索引相关联的值 ///
返回指定索引中关联的值, 如果指定的索引为无效,获取或设置操作将抛出
。 ///
/// 获取或设置值的索引 ///
索引大于集合数量或者小于0
public virtual TValue this[int index] /// /// 复制集合元素到数组中, 以数组的索引开始. /// /// 一维数组
,它是从集合中复制的目标。数组对象必须是从零开始的索引。 /// Array中的从零开始的索引,位于复制开始。 ///
arrayIndex 小于0
///
array 为null
///
/// 数组为多维;或arrayIndex等于或大于数组的长度; /// 或源集合中元素的数量大于arrayIndex到目标数组结束间可用空间。 /// 或者TKey的类型不能自动转换为目标数组的类型。
public virtual void CopyTo(KeyValuePair
[] array, int arrayIndex) ///
/// 创建一个新的对象,它是当前实例的一个副本 /// ///
/// 一个新的对象,此实例的一个副本。 ///
public OrderedDictionary
Clone()

 

2)辅助类OrderedDictionary的使用例子代码如下所示,由于OrderedDictionary在检索的时候效率很高,而且可以通过索引和键进行定位,提供了较好的操作性和方便性。 输出结果如下所示,我们看到,他们虽然可以通过键和索引进行访问,但是他们的顺序不会发生变化。

OrderedDictionary
syncDict = new OrderedDictionary
(); syncDict.Add("A", "testA"); syncDict.Add("C", "testC"); syncDict.Add("B", "TestB"); //通过键访问 StringBuilder sb = new StringBuilder(); foreach (string key in syncDict.Keys) { sb.AppendFormat("{0}:{1}\r\n", key, syncDict[key]); } sb.AppendLine(); //通过索引访问 for (int i = 0; i < syncDict.Keys.Count; i++) { sb.AppendFormat("{0}:{1}\r\n", i, syncDict[i]); } MessageUtil.ShowTips(sb.ToString());

 

3)  辅助类OrderedDictionary和.NET框架内置SortedDictionary不同,他虽然都支持泛型类型,不过键和索引方式访问,后者只是对键进行排序的字典类,并未提供以索引方式进行取值的。

//框架内置的排序字典    SortedDictionary
sortDict = new SortedDictionary
(); sortDict.Add("A", "testA"); sortDict.Add("C", "testC"); sortDict.Add("B", "TestB"); sb = new StringBuilder(); foreach (string key in sortDict.Keys) { sb.AppendFormat("{0}:{1}\r\n", key, sortDict[key]); } MessageUtil.ShowTips(sb.ToString());

而SortedDictionary例子的输出结果如下所示,从中我们可以看到,遍历键的时候,它们已经经过了字母从大到小进行排序了。

 

2、同步的字典集合 SyncDictionary。  

实现效果

1) 现同步的字典集合操作。 一个同步的字典提供一个线程安全的字典集合。

2) 同步字典对象,提供了多线程之间线程安全的访问机制,使你不必担心发送多线程之间的添加、移除、访问等的冲突,放心使用。
3) SyncDictionary类继承了CDictionary类,CDictionary继承了框架的Dictionary类,CDictionary并实现了一些克隆及序列化的接口。SyncDictionary类具有Dictionary类的一切特点,另外他还具备线程安全的特点。

 

实现代码

1)辅助类提供的方法接口如下所示: 

///     /// 获取指定键的关联值    ///     /// 字典键    /// 当此方法返回值时,如果找到该键,便会返回与指定的键相关联的值;否则,则会返回 value 参数的类型默认值。该参数未经初始化即被传递。    /// 
如果字典对象包含具有指定键的元素,则为 true;否则为false.
public new bool TryGetValue(TKey key, out TValue value) /// 获取或设置指定键的值 ///
与指定键关联的值。如果没有找到指定键,KeyNotFoundException将抛出,操作创建一个有指定键的新元素。
/// 设定值的键 ///
键位空
///
属性检索和键在集合不存在。
public new TValue this[TKey key] /// 获取字典对象的键集合 public new KeyCollection Keys /// 获取字典中值的对象集合 public new ValueCollection Values /// 获取
对象,该对象用来比较字典表键的相等
///
对象
通用接口,用来判断当前对象
的相等性, /// 并提供键的哈希值.
public new IEqualityComparer
Comparer ///
/// 获取字典集合中包含键值对的数量 /// ///
///
字典集合中所含元素的数目
public new virtual int Count ///
在集合中移除指定键的元素 ///
如果元素被移除返回true,否则为false。如果原始集合中没有发现指定键的元素,也返回false。
///
待移除元素的键 ///
键为空
public new bool Remove(TKey key) ///
获取迭代结合的枚举器. public new Enumerator GetEnumerator() ///
/// 初始化SyncDictionary对象实例 /// ///
字典对象 public SyncDictionary(CDictionary
dictionary) ///
/// 初始化SyncDictionary对象实例 /// public SyncDictionary() ///
/// 为字典表添加指定的键值 /// ///
待添加元素的键 ///
待添加元素的值. 该值可以是空引用类型. ///
一个具有相同键的元素已经存在于字典
///
键为空
public new void Add(TKey key, TValue value) ///
/// 获取一个值,指出对集合的存取是否同步(线程安全) /// ///
如果词典的访问是同步的(线程安全)则为True,否则为false。默认为false。
public override bool IsSynchronized ///
/// 从字典中移除所有的键值 /// public new void Clear() ///
/// 实现
接口并返回需要序列化字典
实例的数据。 ///
///
一个 SerializationInfo 对象,它包含序列化Dictionary所需的信息。 ///
StreamingContext 结构,该结构包含与 Dictionary相关联的序列化流的源和目标。 ///
info为空引用
[SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] public override void GetObjectData(SerializationInfo info, StreamingContext context) ///
/// 初始化SyncDictionary对象实例 /// ///
对象包含序列化
的必要信息。 ///
A
含有与序列化流
的源和目标的结构。 internal SyncDictionary(SerializationInfo info, StreamingContext context): base(info, context) ///
/// 把ICollection的元素复制到一个KeyValuePair类型的数组,在指定的阵列索引开始。 /// ///
一维数组类型KeyValuePair是从ICollection复制KeyValuePair元素的目标。该数组必须具有从零开始的索引。 ///
array中的从零开始的索引,位于复制开始 public new void CopyTo(KeyValuePair
[] array, int index) ///
/// 实现
接口并抛出反序列化事件,当反序列化完成的时候。 ///
///
反序列化事件的源对象 ///
在当前字典中关联的该对象为无效对象.
public override void OnDeserialization(object sender) ///
/// 确定指定的键是否包含关键。 /// ///
键 ///
/// 如果包含指定的键返回True,否则false。 ///
public new bool ContainsKey(TKey key) ///
/// 判断
是否包含指定的值 ///
///
在字典中待查找的值,如果值是引用类型则可以为null。 ///
/// 如果
包含指定值的元素返回true,否则返回false. ///
public new bool ContainsValue(TValue value)

2)本辅助类主要是用来方便实辅助类SyncDictionary的使用例子代码如下所示,由于SyncDictionary线程安全,非常适合在多线程的环境下进行操作,如Socket服务器处理、后台线程数据处理等环境下。

SyncDictionary
syncDict = new SyncDictionary
(); syncDict.Add("A", "testA"); syncDict.Add("C", "testC"); syncDict.Add("B", "TestB"); //通过键访问 StringBuilder sb = new StringBuilder(); foreach (string key in syncDict.Keys) { sb.AppendFormat("{0}:{1}\r\n", key, syncDict[key]); } sb.AppendLine(); MessageUtil.ShowTips(sb.ToString());

输出结果如下所示,我们看到,他们虽然可以通过键和索引进行访问,但是他们的顺序不会发生变化。

3) 另外它的线程安全,使得其多线程之间的操作也是非常安全、高效的。

SyncDictionary
syncDict = new SyncDictionary
(); private void btnSyncTest_Click(object sender, EventArgs e) { for (int i = 0; i < 5; i++) { Thread thread = new Thread(new ThreadStart(AddSyncDict)); thread.Start(); thread.Join();//等待线程完成才返回主线程 } StringBuilder sb = new StringBuilder(); foreach (string key in syncDict.Keys) { sb.AppendFormat("Key:{0} Value:{1} \r\n", key, syncDict[key]); } MessageUtil.ShowTips(sb.ToString()); } private void AddSyncDict() { string key = new Random().Next().ToString(); if (!syncDict.ContainsKey(key)) { syncDict.Add(key, DateTime.Now.ToString()); } Thread.Sleep(100); }

多线程之间操作的运行效果如下所示

 

3、同步、有序的字典集合 SyncOrderedDictionary。  

实现效果

1)本辅助类主要是用来方便实现同步、有序的字典集合操作。 一个同步的字典提供一个线程安全的字典集合;一个有序的字典是一个集合类,它里面的项目可以通过其索引或他们的键进行操作。。

2) 同步字典对象,提供了多线程之间线程安全的访问机制,使你不必担心发送多线程之间的添加、移除、访问等的冲突,放心使用。
3) 有序集合对象,特点是查找非常高效率,并且提供了强类型的数据操作,不过由于其需要额外在列表中存储数据,因此尽量减少插入或者删除集合对象。
4) 有序的字典集合,虽然存在一些缺点,但是提供了一个非常灵活和用户友好数据结构,允许通过键值或索引进行访问。
5) SyncOrderedDictionary类继承了OrderedDictionary类,具有OrderedDictionary类的一切特点,另外他还具备线程安全的特点。

 

实现代码

1)辅助类提供的方法接口如下所示: 

 接口综合了以上两种(同步、有序)字典类的特点,接口代码不在粘贴出来。

 

2)辅助类SyncOrderedDictionary的使用例子代码如下所示,由于SyncOrderedDictionary在检索的时候效率很高,而且可以通过索引和键进行定位,提供了较好的操作性和方便性。另外由于线程安全,非常适合在多线程的环境下进行操作,如Socket服务器处理、后台线程数据处理等环境下。

SyncOrderedDictionary
syncDict = new SyncOrderedDictionary
(); syncDict.Add("A", "testA"); syncDict.Add("C", "testC"); syncDict.Add("B", "TestB"); //通过键访问 StringBuilder sb = new StringBuilder(); foreach (string key in syncDict.Keys) { sb.AppendFormat("{0}:{1}\r\n", key, syncDict[key]); } sb.AppendLine(); //通过索引访问 for (int i = 0; i < syncDict.Keys.Count; i++) { sb.AppendFormat("{0}:{1}\r\n", i, syncDict[i]); } MessageUtil.ShowTips(sb.ToString());

输出结果如下所示,我们看到,他们虽然可以通过键和索引进行访问,但是他们的顺序不会发生变化。

 

4、同步的列表集合 SyncList。  

实现效果

1) 本辅助类主要是用来方便实现同步列表集合操作。 一个同步的列表集合提供一个线程安全的列表集合;

2)同步字典对象,提供了多线程之间线程安全的访问机制,使你不必担心发送多线程之间的添加、移除、访问等的冲突,放心使用。

 

实现代码

1)辅助类提供的方法接口如下所示,该类继承一个自定义的CList,CList实现了克隆等一些接口,SyncList的函数接口定义如下: 

///     /// 初始化一个同步列表对象实例    ///  public SyncList()    ///     /// 初始化一个同步列表对象实例    ///     /// The list. public SyncList(CList
list) ///
/// 获取一个值,判断
是否为同步的(线程安全). ///
///
如果为同步(线程安全)的,返回true,否则false. 默认为false
///
如果为同步(线程安全)的,返回true,否则false
public override bool IsSynchronized ///
添加一个对象到
末尾.
///
待添加的对象. 值可以为空引用类型。 public new void Add(T item) ///
添加一个集合到
末尾
///
其集合元素待添加到
末尾的集合. /// 集合本身不能为空,但如果类型TKey是一个引用类型,则它包含的元素可以为空 ///
集合为空
public new void AddRange(IEnumerable
collection) ///
/// 为当前集合返回一个只读的
包装类。 ///
public new ReadOnlyCollection
AsReadOnly() ///
/// 从
集合中移除所有对象。 ///
public new void Clear() ///
判定指定的元素是否在
中.
///
如果元素在
中存在返回true,否则返回false.
///
待查找的元素,如果值为引用类型则可以为null public new bool Contains(T item) ///
/// 转换当前
的元素到另外的类型,并返回包含转换后的元素列表。 ///
///
一个
集合,包含当前集合转换后的元素。
///
每个元素从一种类型到另一种类型的转换委托 ///
converter 为 null.
public new CList
ConvertAll
(Converter
converter) ///
复制整个
到一个一维数组中
///
一维数组,从列表中复制元素的目标对象。该数组必须具有从零开始的索引。 ///
源列表中元素的数量大于目标数组能容纳的数量
///
array 为 null.
public new void CopyTo(T[] array) ///
复制整个
到一个一维数组中
///
一维数组,从列表中复制元素的目标对象。该数组必须具有从零开始的索引。 ///
array中的从零开始的索引,位于复制开始。 ///
arrayIndex 大于或等于array数组长度;或源列表的元素数量大于目标array数组从arrayIndex到结束的可用空间
///
arrayIndex 小于等于 0.
///
array 为 null.
public new void CopyTo(T[] array, int arrayIndex) ///
/// 从列表中复制一个范围内的元素到一个相容的一维数组中。以指定的目标索引开始。 /// ///
在从零开始的索引,位于复制开始的源。 ///
一维数组,从列表中复制元素的目标对象。该数组必须具有从零开始的索引。 ///
array中的从零开始的索引,位于复制开始。 ///
待复制的元素数量. ///
array 为 null.
///
index 小于 0;或者arrayIndex 小于0;或者count 小于 0.
///
index 大于或等于源列表的数量。或者arrayIndex 大于或等于数组array的长度。或者从index到源列表结束的元素数量大于从 arrayIndex 到数组array结束的可用空间。
public new void CopyTo(int index, T[] array, int arrayIndex, int count) ///
/// 判定
是否包含符合定义在指定predicate的条件中包含有元素。
///
如果列表中包含指定条件的元素,返回true,否则为false。
///
定义元素的条件来搜索对象的委托 ///
match 为 null.
public new bool Exists(Predicate
match) ///
根据定义条件查询一个元素,并返回第一个在整个列表中出现的元素. ///
根据查询条件,第一个在整个列表中出现的元素,如果没有找到,返回Tkey类型的默认值。
///
定义元素的条件来搜索的委托 ///
match 为 null.
public new T Find(Predicate
match) ///
获取指定Predicate定义的条件相匹配的所有元素。 ///
如果遭到元素,返回指定Predicate定义的条件相匹配的所有元素列表,否则返回一个空列表。.
///
定义元素的条件来搜索的委托 ///
match 为 null.
public new CList
FindAll(Predicate
match) 。。。。。。。。。。。。。。。。。

  

2)辅助类SyncList的使用例子代码如下所示,由于线程安全,非常适合在多线程的环境下进行操作,如Socket服务器处理、后台线程数据处理等环境下。

SyncList
syncList = new SyncList
(); private void btnSyncTest_Click(object sender, EventArgs e) { for (int i = 0; i < 5; i++) { Thread thread = new Thread(new ThreadStart(AddSyncList)); thread.Start(); thread.Join();//等待线程完成才返回主线程 } StringBuilder sb = new StringBuilder(); foreach (string item in syncList) { sb.AppendFormat("item:{0} \r\n", item); } MessageUtil.ShowTips(sb.ToString()); } private void AddSyncList() { string key = new Random().Next().ToString(); syncList.Add(key); Thread.Sleep(100); }

输出结果如下所示。

5、线程安全的先进先出队列辅助类 Fifo。  

实现效果

1) 本辅助类主要是用来方便实现线程安全的先进先出队列操作。

2)线程安全的先进先出队列,提供了多线程之间线程安全的访问机制,使你不必担心发送多线程之间的进队、出队等的冲突,放心使用。
3)Fifo类组合了先进先出的Queue类,提供了线程安全的操作,称为队列或环形缓冲区,这是一种采用先进先出结构(FIFO)的数据结构。现实生活中这种结构应用得非常广泛。比如某些公司的货仓管理系统,要求将先生产的货物先出货,后生产的货物后出货。另外一种场景就是Socket数据包处理的时候,我们一般是把他放到Fifo队列里面,实现先进先出的合理处理。

 

实现代码

1)辅助类提供的方法接口如下所示: 

///     /// 队列中目前存在个数    ///  public int Count    ///     /// 队列的最大容量    ///  public int MaxCount    ///     /// 重新设置队列的最大容量    ///     /// 大于1的整数 public void ResetMaxCount(int MaxCount)    ///     /// 元素进队, 将指定的对象值添加到队列的尾部    ///     /// T 型的参数 public void Append(T obj)    ///     /// 元素出队,即移除队列中开始的元素,按先进先出(FIFO)的规则,从前向后移除元素。    ///     /// 
public T Pop()

 

2)辅助类Fifo的使用例子代码如下所示,由于Fifo线程安全,非常适合在多线程的环境下进行操作,如Socket服务器处理、后台线程数据处理等环境下。 

///     /// 组包后数据的队列(先进先出)    ///  protected Fifo
_preDataFifo = new Fifo
(50000); ///
/// 接收处理数据 /// ///
包体 public void AppendPreData(PreData data) { this._preDataFifo.Append(data); } ///
/// 数据处理 /// protected virtual void PreDataHandle() { try { while (true) { PreData data = _preDataFifo.Pop(); if (data != null) { PreDataHandle(data); } } } catch(Exception ex) { string message = string.Format("[{0}.PreDataHandle] desc:接收器处理异常->{1}", this._Name, ex.ToString()); Log.WriteError(message, ex.ToString(), true); } } ///
/// 对每一个包体的数据进行处理 /// ///
包体 public virtual void PreDataHandle(PreData data) { }

6、各种常用数组排序操作辅助类 SortHelper。  

实现效果

 1) 本辅助类主要是用来方便实现各种常用数组排序操作,包括冒泡排序法、插入排序法、选择排序法、希尔排序法、快速排序法。 

2) 本辅助类提供一些常用的排序操作,也可以作为学习排序的基础教程。

 

实现代码

1)辅助类提供的方法接口如下所示: 

///     /// 冒泡排序法 ///     /// 待排序数组 public static void BubbleSort(int[] list)    ///     /// 插入排序法    ///     /// 待排序数组 public static void InsertionSort(int[] list)    ///     /// 选择排序法    ///     /// 待排序数组 public static void SelectionSort(int[] list)    ///     /// 希尔排序法    ///     /// 待排序数组 public static void ShellSort(int[] list)    ///     /// 快速排序法    ///     /// 待排序数组    /// 低位    /// 高位 public static void QuickSort(int[] list, int low, int high)

2)辅助类SortHelper的使用例子代码如下所示。

private void btnSort_Click(object sender, EventArgs e)    {    //冒泡排序法        int[] list = new int[10] { 0, 1, 2, 3, 4, 9, 8, 7, 6, 5 };        SortHelper.BubbleSort(list);        StringBuilder sb = new StringBuilder();    foreach (int i in list)        {            sb.AppendFormat("{0},", i);        }        MessageUtil.ShowTips(sb.ToString());    //插入排序法        list = new int[10] { 0, 1, 2, 3, 4, 9, 8, 7, 6, 5 };        SortHelper.InsertionSort(list);        sb = new StringBuilder();    foreach (int i in list)        {            sb.AppendFormat("{0},", i);        }        MessageUtil.ShowTips(sb.ToString());    }

其他的接口排序差不多也是如此调用和结果的,只是在排序效率上有所差异。

转载地址:http://futax.baihongyu.com/

你可能感兴趣的文章
【Kernal Support Vector Machine】林轩田机器学习技术
查看>>
CSS+DIV学习笔记——页面布局
查看>>
让所有浏览器支持HTML5 video视频标签
查看>>
Socket 详解
查看>>
[Android Pro] Java进阶学习:jar打包详解
查看>>
xampp-apache配置
查看>>
Linux平台Cpu使用率的计算
查看>>
fiddler(二)、配置抓取https协议
查看>>
php环境配置
查看>>
zabbix专题:第十二章 zabbix proxy分布式监控配置
查看>>
tar 命令的详解
查看>>
Android Studio第二十七期 - RecycleView不同item布局
查看>>
穷人的分布式网络
查看>>
FR-TO-FR本地交换
查看>>
Python内置容器(2)——字典,迭代器,列表解析
查看>>
那年匆匆 -大学
查看>>
Internet 打印提示“打印机安装失败、打印机名称无效”的解决
查看>>
从Powershell ***脚本学到的如何执行后台runspace~
查看>>
SCCM TP4部署Office2013
查看>>
Linux系统启动过程,grub重装。
查看>>