C# volatile与lock

一、C#中volatile

volatile是C#中用于控制同步的关键字,其意义是针对程序中一些敏感数据,不允许多线程同时访问,保证数据在任何访问时刻,最多有一个线程访问,以保证数据的完整性,volatile是修饰变量的修饰符。

1、volatile的使用场景

多个线程同时访问一个变量,CLR为了效率,允许每个线程进行本地缓存,这就导致了变量的不一致性。volatile就是为了解决这个问题,volatile修饰的变量,不允许线程进行本地缓存,每个线程的读写都是直接操作在共享内存上,这就保证了变量始终具有一致性。

2、volatile 关键字可应用于以下类型的字段

(1)、引用类型

(2)、整型,如 sbyte、byte、short、ushort、int、uint、char、float 和 bool。

(3)、具有整数基类型的枚举类型。

(4)、已知为引用类型的泛型类型参数。

(5)、不能将局部变量声明为 volatile。

二、C#中lock

1、lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。此语句的形式如下:

Object thisLock = new Object();
lock (thisLock)
{
    // Critical code section
}

2、lock确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它就会被阻止,直到该对象被释放。也就是说在用到临界资源,确保线程可以排队进入执行临界区中的方法。

3、lock的使用场景

多个线程同时访问一个代码块,使用lock 修饰该代码块,强制多个线程进行排队,一个接一个的去访问。

1、通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。

时间: 2024-10-29 04:16:18

C# volatile与lock的相关文章

[转帖]synchronized、volatile、Lock详解

synchronized.volatile.Lock详解 https://blog.csdn.net/u012102104/article/details/79231159   在Java并发编程过程中,我们难免会遇到synchronized.volatile和lock,其中lock是一个类,而其余两个则是Java关键字.以下记录了小博开发过程中对这三者的理解,不足之处请多指教. 关于线程与进程请参考博文 以操作系统的角度述说线程与进程 synchronized  synchronized是Ja

volatile和lock的使用场景

volatile:多个线程同时访问一个变量,CLR为了效率,允许每个线程进行本地缓存,这就导致了变量的不一致性.volatile就是为了解决这个问题,volatile修饰的变量,不允许线程进行本地缓存,每个线程的读写都是直接操作在共享内存上,这就保证了变量始终具有一致性. lock:多个线程同时访问一个代码块,使用lock 修饰该代码块,同时只能有一个线程访问,其余线程进行排队等待.

volatile与lock前缀指令

前言 我们知道volatile关键字的作用是保证变量在多线程之间的可见性,它是java.util.concurrent包的核心,没有volatile就没有这么多的并发类给我们使用. 本文详细解读一下volatile关键字如何保证变量在多线程之间的可见性,在此之前,有必要讲解一下CPU缓存的相关知识,掌握这部分知识一定会让我们更好地理解volatile的原理,从而更好.更正确地地使用volatile关键字. CPU缓存 CPU缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾,因为C

Volatile vs. Interlocked vs. lock

今天在stackoverflow上看到一个关于Volatile, Interlock, Lock的问题,发现回答的特别好,所以就想到把它翻译一下, 希望给那些对它们有疑惑的人提供点帮助 :假设有一个类,它含有一个可以被多线程访问的public int counter 字段, 这个数字只会增加或减少. 当去增加这个字段的时候,应该采用下面哪个方案,为什么? lock(this.locker) this.counter++; Interlocked.Increment(ref this.counte

volatile原理

内存可见性 内存可见性相关概念:线程对共享变量修改的可见性.当一个线程修改了共享变量的值,其他线程能够立刻得知这个修改. 后面会继续总结一篇<Java内存模型(JMM)总结>以详细描述内存可见性的概念. volatile使用Lock前缀的指令禁止线程本地内存缓存,保证不同线程之间的内存可见性. Java代码如下: Singleton volatile instance = new Singleton();                // instance是volatile变量 转变成汇编代

Java内存模型

多线程如何通信,同步? 1)通信: 共享内存/消息队列 2)同步: 访问时加锁/消息队列 JMM采用共享内存以及访问时加锁.JMM决定一个线程对变量的写入何时对另一个线程可见. Java中,静态变量/实例变量/数组元素都分配在堆中,而局部变量/方法参数/异常变量分配在栈中.线程共享堆,但是独有栈.所以栈不存在共享可见性问题. 每个线程有自己的工作内存,可能是缓存/写缓冲区/寄存器等.线程间通信时,线程A先写到工作内存,再刷新到主内存:然后线程B从主内存读取最新数据到工作内存并创建副本.由于存在重

java面试题一

个人的一点参考总结,如有雷同,纯属巧合! 1.hashmap的实现原理以及hashtable的线程安全是怎么实现的?HashMap其实也是一个线性的数组实现的,所以可以理解为其存储数据的容器就是一个线性数组.首先HashMap里面实现一个静态内部类Entry,其重要的属性有 key , value, next,从属性key,value我们就能很明显的看出来Entry就是HashMap键值对实现的一个基础bean,我们上面说到HashMap的基础就是一个线性数组,这个数组就是Entry[],Map

谈论高并发(七)几个自旋锁的实现(二)

在谈论高并发(六)几个自旋锁的实现(一) 这篇中实现了两种主要的自旋锁:TASLock和TTASLock,它们的问题是会进行频繁的CAS操作.引发大量的缓存一致性流量,导致锁的性能不好. 对TTASLock的一种改进是BackoffLock,它会在锁高争用的情况下对线程进行回退,降低竞争,降低缓存一致性流量.可是BackoffLock有三个基本的问题: 1. 还是有大量的缓存一致性流量,由于全部线程在同一个共享变量上旋转,每一次成功的获取锁都会产生缓存一致性流量 2. 由于回退的存在,不能及时获

设计模式(一)单例模式:6-登记模式

思想: 在之前说到单元素枚举类,有提及到继承的情况. 说起单例模式,不管是什么方法实现的,有一点共性是不变的:不对外提供构造器,即将构造器的权限设为 private. 在一般情况下,以上方法是通用的,但是如果考虑到这个类的结构可能很复杂,会抽象出一个父类出来(不是指抽象类),那么如果这个父类也要保持单例,那么就不能将父类的构造器的权限设为 private 了. 这时,要保证做到以下两点:一个良好包结构设计 && 一个 protected 的构造器. 登记模式,是指所有的子类,都统一通过父类