柳州团购汽车网站建设,做一个企业的网站怎么做的,带注册登录的网站模板,新加坡的网站域名#x1f4e2;欢迎点赞 #xff1a;#x1f44d; 收藏 ⭐留言 #x1f4dd; 如有错误敬请指正#xff0c;赐人玫瑰#xff0c;手留余香#xff01;#x1f4e2;本文作者#xff1a;由webmote 原创#x1f4e2;作者格言#xff1a;新的征程#xff0c;我们面对的不仅… 欢迎点赞 收藏 ⭐留言 如有错误敬请指正赐人玫瑰手留余香本文作者由webmote 原创作者格言新的征程我们面对的不仅仅是技术还有人心人心不可测海水不可量唯有技术才是深沉黑夜中的一座闪烁的灯塔 序言 多线程下的变量访问就如同脚踏几只船的海王在其精细的时间管理下安排每一个女朋友约会一不小心就很可能打翻友谊的小船彻底坠入无尽的大海深处…
而为了让各位亲爱的猿们在约会对象之间横跳的时候能优雅的控制住频率编程语言引入了多个关键字和对象类完成相关操作。
让我们逐个看看这些概念都能完成什么样的奇葩事件吧
1. Volatile 修饰符关键字
volatile 关键字通常被用来表示一个字段的值很可能被多个线程修改因此在编译器VS编译时不要进行优化也不被缓存在编译器或硬件寄存器里。
volatile 关键字确保每次读取和写入时其值都是直接从内存中拿出来的避免任何的优化和缓存。
被volatile 关键字标识的信息就如同海王的A女友信息每次海王想知道A女友的信息时都显示的是A的最新信息而不是从其他人打探的过时信息。有了第一手的信息才能最大程度的避免不慎翻船。
让我们来个模拟例子吧由于编译器的优化准备这个例子着实不易。
//让我们在.net6下测试下...
Console.WriteLine(开始测试...);
var test new Test();
new Thread(delegate () { Thread.Sleep(500); test.foo 255; }).Start();
while (test.foo ! 255) ;
Console.WriteLine(不好了A女友正在抵达战场!);
Console.ReadLine();public class Test
{public int foo 0;
}如果你运行在Debug版本下这时候你是可以收到A女友的抵达信息的。但是一旦你发布成Release这个时候命运的齿轮开始转动你忽然收不到重要的抵达信息了随着时间滴答滴答流动危险的气息扑面而至。
你也试试看切换到Release版本按CtrlF5, 界面如下 这个时候volatile关键字的重要性就体现出来了我们修改下如下信息
public class Test
{public volatile int foo 0;
}看吧一个volatile就救了你一条命。
volatile的使用注意事项
volatile关键字通常用于多线程应用程序中用于处理由多个线程同时访问的共享字段。volatile不用于同步;它仅确保单个读取和写入操作的可见性和原子性。如果需要同步来强制执行顺序或互斥请考虑使用其他同步机制如lock,Monitor,Semaphore 。在多线程方案中处理共享数据时通常建议使用lock 关键字或其他原子操作类因为仅使用volatile关键字可能不足以满足复杂的同步要求。volatile关键字用于字段修饰一般常用的是整型、布尔、指针当然还有引用类型一般指地址
一般关闭线程的布尔值是最佳使用场景。
单例的双重检查锁场景也是有用的例如
public class Singleton {
private static volatile Singleton _instance null;
private static Object _locker new Object();
public static Singleton GetSingleValue()
{if (_instance null){lock(_locker){if (_instance null){ _ instance new Singleton(); }}}return _ instance;
}当然有更简单的写法那就是利用Lazy类
public class Singleton
{private static readonly LazySingleton _instance new LazySingleton(() new Singleton());private Singleton(){}public static Singleton Instance{get{return _instance.Value;}}
}2. Lock 锁锁住要锁的人
锁lock是最好用的保护机制之一了。 锁住资源让其他线程都在后面排队这样就不会撞到一块了。 话说海王的日程表必须有锁没有锁的海王都死翘翘了。
这里是个简单的例子
private object mylock new object();public int A {get {int result;lock(mylock) {result mA; }return result;} set { lock(mylock) { mA value; }}
}作为演示这个例子足够简单作为深度学习这个例子并不好。
大部分类的属性都不需要lock操作使用 public DateTime CreatedTime{get;set;}就已经足够了。因为基础类型都是原子操作的因此没必要去锁定除非你在getset里有更复杂的操作。
因此大可不必都增加上lock 如果是多个线程访问那么不妨增加上 volatile当然属性没法直接增加,有需要多写代码了。
3.Interlocked 非锁的原子操作
锁是独一无二的那么对于时间管理大师们来说这并不是好消息。
那么有什么其他办法既能满足大师们同时多个骚操作又能正常而及时的得到通知呢那就不得不提Interlocked 了经济实惠的确是居家旅行必备良词。
public class NuclearPowerPlant
{private long _meltdownIsHappening 0;public bool MeltdownIsHappeningRightNow {get{/* 锁定操作仅仅支持整型那么我们使用它替换布尔。*/return Interlocked.Read(ref _meltdownIsHappening) 1;}set{Interlocked.Exchange(ref _meltdownIsHappening, Convert.ToInt64(value));}}
}这效率嘎嘎的高。
注意 Interlocked.Increment(ref this.counter); 在实现上等同于lock(this.locker) this. Counter;,不过效率吗那是翻了几倍。可惜的是好东西总有限制。Interlocked仅仅支持整数类型。
4. Synchronized 同步操作
Synchronized 关键字总有点像从哪里抄过来的因此这个用法并不常见。 不过它的含义倒是很清晰就是同一时刻仅允许一个线程访问。
代码如下
public class Test
{public volatile int foo 0;[MethodImpl(MethodImplOptions.Synchronized)]public int Add(int a){return foo a;}
}MethodImpl(MethodImplOptions.Synchronized)这个属性的实现也很简单就是粗暴的lock(this)。
因此不建议直接使用。 总结
哦哦哦好像意犹未尽不过时间有限先到此为止吧。
都看到这了还在乎点个赞吗
都点赞了还在乎一个收藏吗
都收藏了还在乎一个评论吗