时间:2021-05-20
在C#中,用于存储的结构较多,如:DataTable,DataSet,List,Dictionary,Stack等结构,各种结构采用的存储的方式存在差异,效率也必然各有优缺点。现在介绍一种后进先出的数据结构。
谈到存储结构,我们在项目中使用的较多。对于Task存储结构,栈与队列是类似的结构,在使用的时候采用不同的方法。C#中栈(Stack)是编译期间就分配好的内存空间,因此你的代码中必须就栈的大小有明确的定义;堆是程序运行期间动态分配的内存空间,你可以根据程序的运行情况确定要分配的堆内存的大小。
在C#中,栈通常保存着我们代码执行的步骤。C#中的引用类型存储在栈中,在程序运行的时候,每个线程(Thread)都会维护一个自己的专属线程堆栈。当一个方法被调用的时候,主线程开始在所属程序集的元数据中,查找被调用方法,然后通过JIT即时编译并把结果(一般是本地CPU指令)放在栈顶。CPU通过总线从栈顶取指令,驱动程序以执行下去。
以上对栈这个数据结构进行了一个简单的介绍,现在看一下C#实现栈结构的底层方法:
以上是对stack的部分方法的介绍,由于在操作数据存储的同时,会考虑到线程的安全性。
进程作为操作系统执行程序的基本单位,拥有应用程序的资源,进程包含线程,进程的资源被线程共享,线程不拥有资源。线程分为前台线程和后台线程,通过Thread类新建线程默认为前台线程。当所有前台线程关闭时,所有的后台线程也会被直接终止,不会抛出异常。
接下来看一下ReaderWriterLockSlim类:
/// <summary> /// 表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问。 /// </summary> [__DynamicallyInvokable] [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true, Synchronization = true)] [HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)] public class ReaderWriterLockSlim : IDisposable { /// <summary> /// 使用默认属性值初始化 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 类的新实例。 /// </summary> [__DynamicallyInvokable] public ReaderWriterLockSlim(); /// <summary> /// 在指定锁定递归策略的情况下初始化 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 类的新实例。 /// </summary> /// <param name="recursionPolicy">枚举值之一,用于指定锁定递归策略。</param> [__DynamicallyInvokable] public ReaderWriterLockSlim(LockRecursionPolicy recursionPolicy); /// <summary> /// 尝试进入读取模式锁定状态。 /// </summary> /// <exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入读取的模式。- 或 -当它已经包含写入锁时,当前线程可能不会获取读的锁定。- 或 -递归数将超出该计数器的容量。此限制是很大的应用程序应永远不会遇到它。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception> [__DynamicallyInvokable] public void EnterReadLock(); /// <summary> /// 尝试进入读取模式锁定状态,可以选择超时时间。 /// </summary> /// /// <returns> /// 如果调用线程已进入读取模式,则为 true;否则为 false。 /// </returns> /// <param name="timeout">等待的间隔;或为 -1 毫秒,表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="timeout"/> 为负数,但它不等于-1 毫秒为单位),这是唯一允许的值为负。- 或 -值 <paramref name="timeout"/> 大于 <see cref="F:System.Int32.MaxValue"/> 毫秒为单位)。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception> [__DynamicallyInvokable] public bool TryEnterReadLock(TimeSpan timeout); /// <summary> /// 尝试进入读取模式锁定状态,可以选择整数超时时间。 /// </summary> /// /// <returns> /// 如果调用线程已进入读取模式,则为 true;否则为 false。 /// </returns> /// <param name="millisecondsTimeout">等待的毫秒数,或为 -1 (<see cref="F:System.Threading.Timeout.Infinite"/>),表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="millisecondsTimeout"/> 为负数,但它不是等于 <see cref="F:System.Threading.Timeout.Infinite"/> (-1),这是唯一允许的值为负。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception> [__DynamicallyInvokable] public bool TryEnterReadLock(int millisecondsTimeout); /// <summary> /// 尝试进入写入模式锁定状态。 /// </summary> /// <exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已在任何模式下进入该锁。- 或 -当前线程已进入读取的模式,因此尝试进入锁定状态写模式,则会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception> [__DynamicallyInvokable] public void EnterWriteLock(); /// <summary> /// 尝试进入写入模式锁定状态,可以选择超时时间。 /// </summary> /// /// <returns> /// 如果调用线程已进入写入模式,则为 true;否则为 false。 /// </returns> /// <param name="timeout">等待的间隔;或为 -1 毫秒,表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入写入模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="timeout"/> 为负数,但它不等于-1 毫秒为单位),这是唯一允许的值为负。- 或 -值 <paramref name="timeout"/> 大于 <see cref="F:System.Int32.MaxValue"/> 毫秒为单位)。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception> [__DynamicallyInvokable] public bool TryEnterWriteLock(TimeSpan timeout); /// <summary> /// 尝试进入写入模式锁定状态,可以选择超时时间。 /// </summary> /// /// <returns> /// 如果调用线程已进入写入模式,则为 true;否则为 false。 /// </returns> /// <param name="millisecondsTimeout">等待的毫秒数,或为 -1 (<see cref="F:System.Threading.Timeout.Infinite"/>),表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入写入模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="millisecondsTimeout"/> 为负数,但它不是等于 <see cref="F:System.Threading.Timeout.Infinite"/> (-1),这是唯一允许的值为负。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception> [__DynamicallyInvokable] public bool TryEnterWriteLock(int millisecondsTimeout); /// <summary> /// 尝试进入可升级模式锁定状态。 /// </summary> /// <exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已在任何模式下进入该锁。- 或 -当前线程已进入读取的模式,因此尝试进入可升级模式将有死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception> [__DynamicallyInvokable] public void EnterUpgradeableReadLock(); /// <summary> /// 尝试进入可升级模式锁定状态,可以选择超时时间。 /// </summary> /// /// <returns> /// 如果调用线程已进入可升级模式,则为 true;否则为 false。 /// </returns> /// <param name="timeout">等待的间隔;或为 -1 毫秒,表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入可升级模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="timeout"/> 为负数,但它不等于-1 毫秒为单位),这是唯一允许的值为负。- 或 -值 <paramref name="timeout"/> 大于 <see cref="F:System.Int32.MaxValue"/> 毫秒为单位)。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception> [__DynamicallyInvokable] public bool TryEnterUpgradeableReadLock(TimeSpan timeout); /// <summary> /// 尝试进入可升级模式锁定状态,可以选择超时时间。 /// </summary> /// /// <returns> /// 如果调用线程已进入可升级模式,则为 true;否则为 false。 /// </returns> /// <param name="millisecondsTimeout">等待的毫秒数,或为 -1 (<see cref="F:System.Threading.Timeout.Infinite"/>),表示无限期等待。</param><exception cref="T:System.Threading.LockRecursionException"><see cref="P:System.Threading.ReaderWriterLockSlim.RecursionPolicy"/> 属性是 <see cref="F:System.Threading.LockRecursionPolicy.NoRecursion"/> 和当前的线程已进入该锁。- 或 -当前线程最初在读取模式中,输入该锁,因此尝试进入可升级模式会创建导致死锁的可能性。- 或 -递归数将超出该计数器的容量。限制为应用程序应永远不会遇到它太大。</exception><exception cref="T:System.ArgumentOutOfRangeException">值 <paramref name="millisecondsTimeout"/> 为负数,但它不是等于 <see cref="F:System.Threading.Timeout.Infinite"/> (-1),这是唯一允许的值为负。</exception><exception cref="T:System.ObjectDisposedException"><see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象已被释放。</exception> [__DynamicallyInvokable] public bool TryEnterUpgradeableReadLock(int millisecondsTimeout); /// <summary> /// 减少读取模式的递归计数,并在生成的计数为 0(零)时退出读取模式。 /// </summary> /// <exception cref="T:System.Threading.SynchronizationLockException">在读取模式中,当前线程不已进入该锁。</exception> [__DynamicallyInvokable] public void ExitReadLock(); /// <summary> /// 减少写入模式的递归计数,并在生成的计数为 0(零)时退出写入模式。 /// </summary> /// <exception cref="T:System.Threading.SynchronizationLockException">当前线程不已进入写入模式的锁定。</exception> [__DynamicallyInvokable] public void ExitWriteLock(); /// <summary> /// 减少可升级模式的递归计数,并在生成的计数为 0(零)时退出可升级模式。 /// </summary> /// <exception cref="T:System.Threading.SynchronizationLockException">当前线程不已进入可升级模式的锁定。</exception> [__DynamicallyInvokable] public void ExitUpgradeableReadLock(); /// <summary> /// 释放 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 类的当前实例所使用的所有资源。 /// </summary> /// <exception cref="T:System.Threading.SynchronizationLockException"><see cref="P:System.Threading.ReaderWriterLockSlim.WaitingReadCount"/> 是大于零。- 或 -<see cref="P:System.Threading.ReaderWriterLockSlim.WaitingUpgradeCount"/> 是大于零。- 或 -<see cref="P:System.Threading.ReaderWriterLockSlim.WaitingWriteCount"/> 是大于零。</exception><filterpriority>2</filterpriority> [__DynamicallyInvokable] public void Dispose(); /// <summary> /// 获取一个值,该值指示当前线程是否已进入读取模式的锁定状态。 /// </summary> /// /// <returns> /// 如果当前线程已进入读取模式,则为 true;否则为 false。 /// </returns> /// <filterpriority>2</filterpriority> [__DynamicallyInvokable] public bool IsReadLockHeld { [__DynamicallyInvokable] get; } /// <summary> /// 获取一个值,该值指示当前线程是否已进入可升级模式的锁定状态。 /// </summary> /// /// <returns> /// 如果当前线程已进入可升级模式,则为 true;否则为 false。 /// </returns> /// <filterpriority>2</filterpriority> [__DynamicallyInvokable] public bool IsUpgradeableReadLockHeld { [__DynamicallyInvokable] get; } /// <summary> /// 获取一个值,该值指示当前线程是否已进入写入模式的锁定状态。 /// </summary> /// /// <returns> /// 如果当前线程已进入写入模式,则为 true;否则为 false。 /// </returns> /// <filterpriority>2</filterpriority> [__DynamicallyInvokable] public bool IsWriteLockHeld { [__DynamicallyInvokable] get; } /// <summary> /// 获取一个值,该值指示当前 <see cref="T:System.Threading.ReaderWriterLockSlim"/> 对象的递归策略。 /// </summary> /// /// <returns> /// 枚举值之一,用于指定锁定递归策略。 /// </returns> [__DynamicallyInvokable] public LockRecursionPolicy RecursionPolicy { [__DynamicallyInvokable] get; } /// <summary> /// 获取已进入读取模式锁定状态的独有线程的总数。 /// </summary> /// /// <returns> /// 已进入读取模式锁定状态的独有线程的数量。 /// </returns> [__DynamicallyInvokable] public int CurrentReadCount { [__DynamicallyInvokable] get; } /// <summary> /// 获取当前线程进入读取模式锁定状态的次数,用于指示递归。 /// </summary> /// /// <returns> /// 如果当前线程未进入读取模式,则为 0(零);如果线程已进入读取模式但却不是以递归方式进入的,则为 1;或者如果线程已经以递归方式进入锁定模式 n - 1 次,则为 n。 /// </returns> /// <filterpriority>2</filterpriority> [__DynamicallyInvokable] public int RecursiveReadCount { [__DynamicallyInvokable] get; } /// <summary> /// 获取当前线程进入可升级模式锁定状态的次数,用于指示递归。 /// </summary> /// /// <returns> /// 如果当前线程没有进入可升级模式,则为 0;如果线程已进入可升级模式却不是以递归方式进入的,则为 1;或者如果线程已经以递归方式进入可升级模式 n - 1 次,则为 n。 /// </returns> /// <filterpriority>2</filterpriority> [__DynamicallyInvokable] public int RecursiveUpgradeCount { [__DynamicallyInvokable] get; } /// <summary> /// 获取当前线程进入写入模式锁定状态的次数,用于指示递归。 /// </summary> /// /// <returns> /// 如果当前线程没有进入写入模式,则为 0;如果线程已进入写入模式却不是以递归方式进入的,则为 1;或者如果线程已经以递归方式进入写入模式 n - 1 次,则为 n。 /// </returns> /// <filterpriority>2</filterpriority> [__DynamicallyInvokable] public int RecursiveWriteCount { [__DynamicallyInvokable] get; } /// <summary> /// 获取等待进入读取模式锁定状态的线程总数。 /// </summary> /// /// <returns> /// 等待进入读取模式的线程总数。 /// </returns> /// <filterpriority>2</filterpriority> [__DynamicallyInvokable] public int WaitingReadCount { [__DynamicallyInvokable] get; } /// <summary> /// 获取等待进入可升级模式锁定状态的线程总数。 /// </summary> /// /// <returns> /// 等待进入可升级模式的线程总数。 /// </returns> /// <filterpriority>2</filterpriority> [__DynamicallyInvokable] public int WaitingUpgradeCount { [__DynamicallyInvokable] get; } /// <summary> /// 获取等待进入写入模式锁定状态的线程总数。 /// </summary> /// /// <returns> /// 等待进入写入模式的线程总数。 /// </returns> /// <filterpriority>2</filterpriority> [__DynamicallyInvokable] public int WaitingWriteCount { [__DynamicallyInvokable] get; } }以上是对Stack和线程的相关知识的浅述,现在介绍一下线程安全的Stack:
以上的操作方法继承了IEnumerable<T>, ICollection两个接口。有兴趣的,可以对IEnumerable<T>, ICollection两个接口进行细致的了解。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C#结构体在C#中,结构体是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。struct关键字用于创建结构体。定义结构体structBooks
值类型:也称为原始数据或原始值(primitivevalue)。这类值存储在栈(stack)中,栈是内存中一种特殊的数据结构,也称为线性表,栈按照后进先出的原则
在上面介绍过栈(Stack)的存储结构,接下来介绍另一种存储结构字典(Dictionary)。字典(Dictionary)里面的每一个元素都是一个键值对(由二个
本文实例讲述了C#使用Object类实现栈的方法。分享给大家供大家参考,具体如下:Stack类的代码:usingSystem;usingSystem.Colle
思路分析:既然是用泛型实现栈结构,那就不能用JDK自带的stack包了,需要自己定义一个栈结构,比如LinkedList。代码如下:Stack.java:复制代