你没用过的.net4.0
项目升级到.net 4.0很久了,但很多语法和知识点,还停留在以前的版本的有木有?
今天,我们就一块来看一下在.net 4.0的环境下我们如何编程的。
先从锁开始。需要你有一点点操作系统和多线程的基础哦。
再拉回过去,在处理并发的时候,平日大家都是如何实现一个锁的呢?
-
Lock
早在1.0时代,就有了Lock关键字,我们想实现一个自增长的场景:让多线程有序的访问静态类JingTai的num字段,不发生并发。
public static class JingTai { public static int num = 0; } class Program { static void Main( string [] args) { //我们想实现一个场景: //让多线程有序的访问静态类JingTai的num字段,不发生并发 int d = 23; Thread[] thread = new Thread[d]; for ( int i = 0; i < d; i++) { thread[i] = new Thread( new ThreadStart(GaiBianJingTai)); thread[i].Start(); } Console.ReadLine(); //这一句只是为了查看结果使用 } static void GaiBianJingTai() { Random r = new Random(); int n = r.Next(111, 1111); Thread.Sleep(n); lock ( typeof (JingTai)) //请注意:如果没有lock(注释此行),每次的结果是不确定的,而且可能有重复的 { Console.WriteLine(JingTai.num++); } } } |
Lock太简单了,我们就不赘述了。继续。。。
-
Monitor
Monitor也可以实现同样的功能,为共享资源加锁;他在.Net2.0的时代就已经出现了。

public static class JingTai { public static int num = 0; } class Program { static void Main(string[] args) { //我们想实现一个场景: //让多线程有序的访问静态类JingTai的num字段,不发生并发 int d = 23; Thread[] thread = new Thread[d]; for (int i = 0; i < d; i++) { thread[i] = new Thread(new ThreadStart(GaiBianJingTai)); thread[i].Start(); } Console.ReadLine();//这一句只是为了查看结果使用 } static void GaiBianJingTai() { Random r = new Random(); int n = r.Next(111, 1111); Thread.Sleep(n); Monitor.Enter(typeof(JingTai)); Console.WriteLine(JingTai.num++); Monitor.Exit(typeof(JingTai)); } }
我们来分析一下使用Monitor,他的致命缺陷在于性能:
线程使用Monitor访问共享的资源时候,如果他不能拿到锁,线程状态会有运行转换为阻塞,只以为着将会进行一个线程上下文的切换。如果每个线程对共享资源的访问时间很短,比如我们的只是num的值加1,那么使用Monitor必然带来频繁的线程上下文的切换,明显影响到程序运行的性能。
好了,镜头拉回现在.net4.0平台,微软才推出了新的自旋锁SpinLock。
-
SpinLock
当一个线程需要访问资源的时候,他调用SpinLock.Enter方法申请独占锁,如果不能获得锁(此时可能运行于另一个CPU核上的线程正在占有这个资源),当前线程就会空转若干个时间片,然后等下次时间片轮询到他的时候,他再尝试申请这个独占锁,在这个过程中该线程一直保持着运行时的状态哦,不会出现上下文的切换。

public class JingTai { public static int num = 0; public int day = 0; } class Program { static void Main(string[] args) { //我们想实现一个场景: //让多线程有序的访问静态类JingTai的num字段,不发生并发 int d = 23; Thread[] thread = new Thread[d]; for (int i = 0; i < d; i++) { thread[i] = new Thread(new ThreadStart(GaiBianJingTai)); thread[i].Start(); } Console.ReadLine();//这一句只是为了查看结果使用 } /* * 以下是微软给出的注意事项 SpinLock 仅当您确定这样做可以改进应用程序的性能之后才能使用。 * 另外,务必请注意 SpinLock 是一个值类型(出于性能原因)。 * 因此,您必须非常小心,不要意外复制了 SpinLock 实例,因为两个实例(原件和副本)之间完全独立,这可能会导致应用程序出现错误行为。 * 如果必须传递 SpinLock 实例,则应该通过引用而不是通过值传递。 * 不要将 SpinLock 实例存储在只读字段中。 */ private static SpinLock spin = new SpinLock();//创建一个自旋锁,注意:他的类型是struct 哦 static void GaiBianJingTai() { bool lockTaken = false; try { spin.Enter(ref lockTaken); Console.WriteLine(JingTai.num++); } finally { if (lockTaken) spin.Exit(); } } }
对于单核CPU,使用SpinLock的效率和Monitor相比差别不大,,但是在多喝CPU环境下,在合适的场景下使用SpinLock取代Monitor,效率大大的提升。
另外,SpinLock 的所有成员都是线程安全的,可从多个线程同时使用。
下一次我想说说.net4.0才有的多核环境下的并行开发。
出处:http://www.cnblogs.com/angben 欢迎转载,也请保留这段声明。谢谢!
好了,今天就说这些,嗯,就这些了。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验