using System;
using System.Threading; /// <summary>
/// Provides lock-free atomic read/write utility for a <c>int</c> value. The atomic classes found in this package
/// were are meant to replicate the <c>java.util.concurrent.atomic</c> package in Java by Doug Lea. The two main differences
/// are implicit casting back to the <c>int</c> data type, and the use of a non-volatile inner variable.
///
/// <para>The internals of these classes contain wrapped usage of the <c>System.Threading.Interlocked</c> class, which is how
/// we are able to provide atomic operation without the use of locks. </para>
/// </summary>
/// <remarks>
/// It's also important to note that <c>++</c> and <c>--</c> are never atomic, and one of the main reasons this class is
/// needed. I don't believe its possible to overload these operators in a way that is autonomous.
/// </remarks>
/// \author Matt Bolt
public class AtomicInt { private int _value; /// <summary>
/// Creates a new <c>AtomicInt</c> instance with an initial value of <c></c>.
/// </summary>
public AtomicInt()
: this() { } /// <summary>
/// Creates a new <c>AtomicInt</c> instance with the initial value provided.
/// </summary>
public AtomicInt(int value) {
_value = value;
} /// <summary>
/// This method returns the current value.
/// </summary>
/// <returns>
/// The value of the <c>int</c> accessed atomically.
/// </returns>
public int Get() {
return _value;
} /// <summary>
/// This method sets the current value atomically.
/// </summary>
/// <param name="value">
/// The new value to set.
/// </param>
public void Set(int value) {
Interlocked.Exchange(ref _value, value);
} /// <summary>
/// This method atomically sets the value and returns the original value.
/// </summary>
/// <param name="value">
/// The new value.
/// </param>
/// <returns>
/// The value before setting to the new value.
/// </returns>
public int GetAndSet(int value) {
return Interlocked.Exchange(ref _value, value);
} /// <summary>
/// Atomically sets the value to the given updated value if the current value <c>==</c> the expected value.
/// </summary>
/// <param name="expected">
/// The value to compare against.
/// </param>
/// <param name="result">
/// The value to set if the value is equal to the <c>expected</c> value.
/// </param>
/// <returns>
/// <c>true</c> if the comparison and set was successful. A <c>false</c> indicates the comparison failed.
/// </returns>
public bool CompareAndSet(int expected, int result) {
return Interlocked.CompareExchange(ref _value, result, expected) == expected;
} /// <summary>
/// Atomically adds the given value to the current value.
/// </summary>
/// <param name="delta">
/// The value to add.
/// </param>
/// <returns>
/// The updated value.
/// </returns>
public int AddAndGet(int delta) {
return Interlocked.Add(ref _value, delta);
} /// <summary>
/// This method atomically adds a <c>delta</c> the value and returns the original value.
/// </summary>
/// <param name="delta">
/// The value to add to the existing value.
/// </param>
/// <returns>
/// The value before adding the delta.
/// </returns>
public int GetAndAdd(int delta) {
for (;;) {
int current = Get();
int next = current + delta;
if (CompareAndSet(current, next)) {
return current;
}
}
} /// <summary>
/// This method increments the value by 1 and returns the previous value. This is the atomic
/// version of post-increment.
/// </summary>
/// <returns>
/// The value before incrementing.
/// </returns>
public int Increment() {
return GetAndAdd();
} /// <summary>
/// This method decrements the value by 1 and returns the previous value. This is the atomic
/// version of post-decrement.
/// </summary>
/// <returns>
/// The value before decrementing.
/// </returns>
public int Decrement() {
return GetAndAdd(-);
} /// <summary>
/// This method increments the value by 1 and returns the new value. This is the atomic version
/// of pre-increment.
/// </summary>
/// <returns>
/// The value after incrementing.
/// </returns>
public int PreIncrement() {
return Interlocked.Increment(ref _value);
} /// <summary>
/// This method decrements the value by 1 and returns the new value. This is the atomic version
/// of pre-decrement.
/// </summary>
/// <returns>
/// The value after decrementing.
/// </returns>
public int PreDecrement() {
return Interlocked.Decrement(ref _value);
} /// <summary>
/// This operator allows an implicit cast from <c>AtomicInt</c> to <c>int</c>.
/// </summary>
public static implicit operator int(AtomicInt value) {
return value.Get();
} }

C# AtomicInt的更多相关文章

  1. Java(JCo3)与SAP系统相互调用

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  2. 非阻塞同步算法与CAS(Compare and Swap)无锁算法

    锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...

  3. Java CAS 和ABA问题

    独占锁:是一种悲观锁,synchronized就是一种独占锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁. 乐观锁:每次不加锁,假设没有冲突去完成某项操作,如果因为冲突失败就重试,直到成功 ...

  4. java CAS

    在Doug Lea提供的cucurenct包 (J.U.C)中,CAS理论是实现整个java包的基石.   Compare and Swap 在这里,CAS 指的是现代 CPU 广泛支持的一种对内存中 ...

  5. (转)乐观的并发策略——基于CAS的自旋

    悲观者与乐观者的做事方式完全不一样,悲观者的人生观是一件事情我必须要百分之百完全控制才会去做,否则就认为这件事情一定会出问题:而乐观者的人生观则相反,凡事不管最终结果如何,他都会先尝试去做,大不了最后 ...

  6. 乐观锁--CAS

    悲观锁与乐观锁的区别 悲观锁会把整个对象加锁占为已有后才去做操作,Java中的Synchronized属于悲观锁.悲观锁有一个明显的缺点就是:它不管数据存不存在竞争都加锁,随着并发量增加,且如果锁的时 ...

  7. ReactiveX序列——RxSwift 浅析

      ReactiveX序列——RxSwift Swift是苹果公司新推出的一门现代化的编程语言,并且将其开源出来了,Swift具有很多的优点,这也使得这门语言推出的短时间引起了很大反应的原因,在最近的 ...

  8. 乐观的并发策略——基于CAS的自旋

    悲观者与乐观者的做事方式完全不一样,悲观者的人生观是一件事情我必须要百分之百完全控制才会去做,否则就认为这件事情一定会出问题:而乐观者的人生观则相反,凡事不管最终结果如何,他都会先尝试去做,大不了最后 ...

  9. ScalaPB(3): gRPC streaming

    接着上期讨论的gRPC unary服务我们跟着介绍gRPC streaming,包括: Server-Streaming, Client-Streaming及Bidirectional-Streami ...

随机推荐

  1. jvm 方法区

    方法区在一个jvm实例的内部,类型信息被存储在一个称为方法区的内存逻辑区中.类型信息是由类加载器在类加载时从类文件中提取出来的.类(静态)变量也存储在方法区中. jvm实现的设计者决定了类型信息的内部 ...

  2. 微信小程序之蓝牙开发(详细读数据、写数据、附源码)

    本文将详细介绍微信小程序的蓝牙开发流程(附源码)准备:微信只支持低功耗蓝牙也就是蓝牙4.0,普通的蓝牙模块是用不了的,一定要注意. 蓝牙可以连TTL接到电脑上,再用XCOM调试 一开始定义的变量 va ...

  3. Eclipse SVN 使用教程

    Eclipse SVN 使用教程 做好以上的准备后打开Eclipse编译器,点击编译器右上角的Open Perspective 打开SVN资源库界面,新建一个资源库 选择资源库的位置,这里我们就用刚才 ...

  4. Port of FreeModbus to STM32

    /********************************************************************************* * Port of FreeMod ...

  5. Word Embeddings

    能够充分意识到W的这些属性不过是副产品而已是很重要的.我们没有尝试着让相似的词离得近.我们没想把类比编码进不同的向量里.我们想做的不过是一个简单的任务,比如预测一个句子是不是成立的.这些属性大概也就是 ...

  6. Appium笔记(一) 丶Appium的自我介绍

    一.我是谁,我的特点是什么 Appium是一款开源测试自动化框架,可用于原生.混合和移动Web应用程序.它使用WebDriver协议驱动iOS,Android和Windows应用程序.重要的是,App ...

  7. 杭电OJ1789、南阳OJ236(贪心法)解题报告

    杭电OJ1789http://acm.hdu.edu.cn/showproblem.php?pid=1789 南阳OJ236http://59.69.128.203/JudgeOnline/probl ...

  8. (1)集合 ---遍历map集合

    Map接口     实现Map接口的类用来存储键(key)-值(value) 对.Map 接口的实现类有HashMap和TreeMap等.Map类中存储的键-值对通过键来标识,所以键值不能重复. Ha ...

  9. sqlserver linux 容器运行

    sqlserver linux 版本的容器大小目前已经相对比较小了,对于开发来说已经比较方便了 docker-compose 文件 version: "3" services: d ...

  10. Javascript 严格模式下几个禁忌

    禁止使用未声明的变量. 禁止删除变量或对象 禁止删除函数 禁止使用八进制 禁止对只读属性赋值 禁止对一个使用getter方法读取的属性进行赋值 禁止删除一个不允许删除的属性 变量名禁止使用 " ...