有关多线程环境下的Volatile、lock、Interlocked和Synchronized们

这篇具有很好参考价值的文章主要介绍了有关多线程环境下的Volatile、lock、Interlocked和Synchronized们。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!
  • 📢本文作者:由webmote 原创
  • 📢作者格言:新的征程,我们面对的不仅仅是技术还有人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔 !

序言

有关多线程环境下的Volatile、lock、Interlocked和Synchronized们,C#入门,开发语言,.net,lock,volatile,synchronize
多线程下的变量访问,就如同脚踏几只船的海王,在其精细的时间管理下安排每一个女朋友约会,一不小心,就很可能打翻友谊的小船,彻底坠入无尽的大海深处…

而为了让各位亲爱的猿们,在约会对象之间横跳的时候,能优雅的控制住频率,编程语言引入了多个关键字和对象类完成相关操作。

让我们逐个看看,这些概念都能完成什么样的奇葩事件吧!

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版本,按Ctrl+F5, 界面如下:

有关多线程环境下的Volatile、lock、Interlocked和Synchronized们,C#入门,开发语言,.net,lock,volatile,synchronize
这个时候,volatile关键字的重要性就体现出来了,我们修改下如下信息:

public class Test
{
    public volatile int foo = 0;
}

有关多线程环境下的Volatile、lock、Interlocked和Synchronized们,C#入门,开发语言,.net,lock,volatile,synchronize
看吧,一个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 Lazy<Singleton> _instance
         = new Lazy<Singleton>(() => new Singleton());
    private Singleton()
    {
    }
     public static Singleton Instance
     {
         get
         {
             return _instance.Value;
         }
     }
}

2. Lock 锁,锁住要锁的人

lock,是最好用的保护机制之一了。 锁住资源,让其他线程都在后面排队,这样就不会撞到一块了。

有关多线程环境下的Volatile、lock、Interlocked和Synchronized们,C#入门,开发语言,.net,lock,volatile,synchronize
话说,海王的日程表,必须有锁,没有锁的海王都死翘翘了。

这里是个简单的例子:

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;}就已经足够了。因为基础类型都是原子操作的,因此没必要去锁定,除非你在get,set里有更复杂的操作。

因此,大可不必都增加上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)

因此,不建议直接使用。

有关多线程环境下的Volatile、lock、Interlocked和Synchronized们,C#入门,开发语言,.net,lock,volatile,synchronize

总结

哦哦哦,好像意犹未尽,不过时间有限,先到此为止吧。

👓都看到这了,还在乎点个赞吗?

👓都点赞了,还在乎一个收藏吗?

👓都收藏了,还在乎一个评论吗?文章来源地址https://www.toymoban.com/news/detail-718851.html

到了这里,关于有关多线程环境下的Volatile、lock、Interlocked和Synchronized们的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Lock和synchronized的区别

    1、Lock是一个接口,而synchronized是一个Java,synchronized是内置的语言实现,Lock是代码层面的实现 2、Lock可以选择性的获取锁,如果一段时间获取不到,咋可以不要了。synchronized不行,不达目的不罢休。借助这个特性,Lock可以避免死锁,而synchronized不惜通过谨慎的设计才

    2024年02月08日
    浏览(39)
  • lock 和synchronized 的区别

    1  lock是接口实现,synchronized是内置方法native实现 2 lock可以主动释放锁,synchronized只能是加锁的代码块执行完毕或者遇到异常退出被动的释放锁 3 性能方面,如果竞争资源不是很激烈的情况,两者的性能差不太多,如果是在竞争资源激烈的情况下,lock的性能要优于synchronize

    2024年02月08日
    浏览(42)
  • Java——》Synchronized和Lock区别

    推荐链接:     总结——》【Java】     总结——》【Mysql】     总结——》【Redis】     总结——》【Kafka】     总结——》【Spring】     总结——》【SpringBoot】     总结——》【MyBatis、MyBatis-Plus】     总结——》【Linux】     总结——》【MongoDB】    

    2024年02月09日
    浏览(41)
  • Synchronized与Lock的区别和优缺点

    1.   synchronized 是 Java 的一个内置特性,而 Lock 是 Java 的一个接口类; 2.   synchronized 在发生异常时会自动释放线程占用的锁,而 Lock 在发生异常时(不发生也一样)需要主动在 finally 中调用 unLock() 去释放锁; 3.   Lock 可以让等待锁的线程响应中断,而 synchronized 无法

    2024年02月08日
    浏览(47)
  • Java并发之synchronized关键字和Lock接口

    欢迎点赞阅读,一同学习交流,有疑问请留言 。 GitHub上也有开源 JavaHouse,欢迎star 当开发过程中,我们遇到并发问题。怎么解决? 一种解决方式,简单粗暴:上锁。将千军万马都给拦下来,只允许一个人过独木桥。书面意思就是将并行的程序变成串行的程序。现实的锁有门锁

    2024年02月08日
    浏览(40)
  • 什么是多线程环境下的伪共享(false sharing)?

    在Java中,伪共享(false sharing)是指多线程环境下,由于缓存一致性协议的影响,不同线程访问同一缓存行中的不同数据造成的性能下降现象。当多个线程同时访问不同变量,但这些变量存储在同一缓存行中时,每个线程只修改自己的变量,但由于缓存一致性协议的要求,需要将

    2024年02月10日
    浏览(39)
  • 【多线程】volatile关键字

    一、volatile 1.volatile的底层原理是内存屏障,Memory Barrier, Memory Fence 2.对volatile变量的写指令(赋值操作)后会加入写屏障 3.对volatile变量的读指令(取变量值)前会加入读屏障 4.写屏障的作用会将写屏障之前的赋值改动操作,对共享变量的改动都同步到主内存中 5.读屏障的作

    2024年02月06日
    浏览(43)
  • 【Linux】volatile | SIGCHLD | 多线程概念

    在vscode中,创建signal.c文件 故意在while中没有写代码块,让编译器认为在main中,quit只会被检测 运行可执行程序后,当输入 2号信号时,调用自定义方法将quit置为1,跳出while循环 编译器有对应的编译优化级别 -O1 -O2 -O3 在makefile中,添加-O2的优化级别 再次执行可执行程序时,输

    2024年02月05日
    浏览(53)
  • 【多线程进阶】synchronized 原理

    在前面章节中, 提到了多线程中的锁策略, 那么我们 Java 中的锁 synchronized 背后都采取了哪些锁策略呢? 又是如何进行工作的呢? 本节我们就来谈一谈. 关注收藏, 开始学习吧🧐 在 Java 中, synchronized 具有以下特性(这里以 JDK 1.8 为例): 开始时是乐观锁, 如果锁冲突频繁, 就转换为悲

    2024年02月07日
    浏览(34)
  • java线程-synchronized详解

    解决线程原子性问题,最常见的手段就是加锁,Java提供了两种加锁的方式,一个synchronized隐式锁,另外一个是通过J.U.C框架提供的Lock显式加锁。本文主要介绍一个Synchronized的实现方式。 synchronized解决的是多个线程之间访问资源的同步性,synchronized 翻译为中文的意思是

    2024年02月10日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包