C# AtomicInt
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的更多相关文章
- Java(JCo3)与SAP系统相互调用
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- 非阻塞同步算法与CAS(Compare and Swap)无锁算法
锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...
- Java CAS 和ABA问题
独占锁:是一种悲观锁,synchronized就是一种独占锁,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁. 乐观锁:每次不加锁,假设没有冲突去完成某项操作,如果因为冲突失败就重试,直到成功 ...
- java CAS
在Doug Lea提供的cucurenct包 (J.U.C)中,CAS理论是实现整个java包的基石. Compare and Swap 在这里,CAS 指的是现代 CPU 广泛支持的一种对内存中 ...
- (转)乐观的并发策略——基于CAS的自旋
悲观者与乐观者的做事方式完全不一样,悲观者的人生观是一件事情我必须要百分之百完全控制才会去做,否则就认为这件事情一定会出问题:而乐观者的人生观则相反,凡事不管最终结果如何,他都会先尝试去做,大不了最后 ...
- 乐观锁--CAS
悲观锁与乐观锁的区别 悲观锁会把整个对象加锁占为已有后才去做操作,Java中的Synchronized属于悲观锁.悲观锁有一个明显的缺点就是:它不管数据存不存在竞争都加锁,随着并发量增加,且如果锁的时 ...
- ReactiveX序列——RxSwift 浅析
ReactiveX序列——RxSwift Swift是苹果公司新推出的一门现代化的编程语言,并且将其开源出来了,Swift具有很多的优点,这也使得这门语言推出的短时间引起了很大反应的原因,在最近的 ...
- 乐观的并发策略——基于CAS的自旋
悲观者与乐观者的做事方式完全不一样,悲观者的人生观是一件事情我必须要百分之百完全控制才会去做,否则就认为这件事情一定会出问题:而乐观者的人生观则相反,凡事不管最终结果如何,他都会先尝试去做,大不了最后 ...
- ScalaPB(3): gRPC streaming
接着上期讨论的gRPC unary服务我们跟着介绍gRPC streaming,包括: Server-Streaming, Client-Streaming及Bidirectional-Streami ...
随机推荐
- antd中fomr中resetFields清空输入框
1.如果没有initValue的情况下,直接使用resetFields可以清空文本框的值 2.如果是有initValue的情况下,直接使用resetFields方法会直接重置为initValue的值 ...
- WCF异常相关
1.端口没打开 解决办法: services.msc 启动Net.Tcp Port Sharing Service 2.由于访问被拒,服务终结点未能侦听 URI“net.tcp://localhost ...
- X11 fluxbox窗口管理器
/********************************************************************************* * X11 fluxbox窗口管理 ...
- TJU Problem 2520 Quicksum
注意: for (int i = 1; i <= aaa.length(); i++) 其中是“ i <= ",注意等号. 原题: 2520. Quicksum Time L ...
- VS2015 LINK : fatal error LNK1264: 已指定 /GENPROFILE 但没有所需的代码生成;检测失败
C/C++ > 优化 > 全程优化 > 是
- PR
3.1音频轨道与播放 单声道音轨: 立体声音轨:立体声音频文件 3.2 音频过渡 需要先把第一段视频的结尾与第二段视频的开头切除,然后在使用恒定功率. 3.3 调音台的简单使用 调节音频: 显示声音 ...
- 八皇后 递归or迭代
递归: #include <iostream> #include <cstdlib> #include <cstdio> using namespace std; ...
- 关于bfs与dfs的标记区别
回顾一下dfs与bfs的使用,由于二者都需要避免走重复的路,所以二者都需要对数组进行标记 而二者的标记操作的不同点是 dfs会对数组的标记进行清除(包含两种标记,一种对形参变量的标记,这个清除是返回上 ...
- OracleDesigner学习笔记1――安装篇
OracleDesigner学习笔记1――安装篇 QQ:King MSN:qiutianwh@msn.com Email:qqking@gmail.com 一. 前言 Oracle是当 ...
- flash TweenMax用法
二,TweenMax主类: 这里分几个大块来介绍,分别是:第三个参数特有属性(29个),PlugIn(17个),公共属性(10个),公共方法(20个). 1,第三个参数特有属性(29个): 这29个参 ...