C# AtomicLong
using System;
using System.Threading; /// <summary>
/// Provides lock-free atomic read/write utility for a <c>long</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>long</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 AtomicLong { private long _value; /// <summary>
/// Creates a new <c>AtomicLong</c> instance with an initial value of <c></c>.
/// </summary>
public AtomicLong()
: this() { } /// <summary>
/// Creates a new <c>AtomicLong</c> instance with the initial value provided.
/// </summary>
public AtomicLong(long value) {
_value = value;
} /// <summary>
/// This method returns the current value.
/// </summary>
/// <returns>
/// The <c>long</c> value accessed atomically.
/// </returns>
public long Get() {
return Interlocked.Read(ref _value);
} /// <summary>
/// This method sets the current value atomically.
/// </summary>
/// <param name="value">
/// The new value to set.
/// </param>
public void Set(long 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 long GetAndSet(long 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(long expected, long 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 long AddAndGet(long 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 long GetAndAdd(long delta) {
for (;;) {
long current = Get();
long 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 long 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 long 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 long 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 long PreDecrement() {
return Interlocked.Decrement(ref _value);
} /// <summary>
/// This operator allows an implicit cast from <c>AtomicLong</c> to <c>long</c>.
/// </summary>
public static implicit operator long(AtomicLong value) {
return value.Get();
} }
C# AtomicLong的更多相关文章
- Java多线程系列--“JUC原子类”02之 AtomicLong原子类
概要 AtomicInteger, AtomicLong和AtomicBoolean这3个基本类型的原子类的原理和用法相似.本章以AtomicLong对基本类型的原子类进行介绍.内容包括:Atomic ...
- AtomicLong
Spring package com.uniubi.management.controller; import java.util.concurrent.atomic.AtomicLong; impo ...
- 多线程爬坑之路-J.U.C.atomic包下的AtomicInteger,AtomicLong等类的源码解析
Atomic原子类:为基本类型的封装类Boolean,Integer,Long,对象引用等提供原子操作. 一.Atomic包下的所有类如下表: 类摘要 AtomicBoolean 可以用原子方式更新的 ...
- [JDK8]性能优化之使用LongAdder替换AtomicLong
如果让你实现一个计数器,有点经验的同学可以很快的想到使用AtomicInteger或者AtomicLong进行简单的封装. 因为计数器操作涉及到内存的可见性和线程之间的竞争,而Atomic***的实现 ...
- JDK1.8 LongAdder 空间换时间: 比AtomicLong还高效的无锁实现
我们知道,AtomicLong的实现方式是内部有个value 变量,当多线程并发自增,自减时,均通过CAS 指令从机器指令级别操作保证并发的原子性. // setup to use Unsafe.co ...
- java多线程之AtomicLong与LongAdder
AtomicLong简要介绍 AtomicLong是作用是对长整形进行原子操作,显而易见,在java1.8中新加入了一个新的原子类LongAdder,该类也可以保证Long类型操作的原子性,相对于At ...
- 使用AtomicLong,经典银行账户问题
1.新建Account类,使用AtomicLong定义账户余额,增加和减少金额方法使用getAndAdd方法. package com.xkzhangsan.atomicpack.bank; impo ...
- AtomicLong和LongAdder的区别
AtomicLong的原理是依靠底层的cas来保障原子性的更新数据,在要添加或者减少的时候,会使用死循环不断地cas到特定的值,从而达到更新数据的目的. LongAdder在AtomicLong的基础 ...
- 【Java多线程】AtomicLong和LongAdder
AtomicLong简要介绍 AtomicLong是作用是对长整形进行原子操作,显而易见,在java1.8中新加入了一个新的原子类LongAdder,该类也可以保证Long类型操作的原子性,相对于At ...
- AtomicLong.lazySet 是如何工作的?
原文:http://www.quora.com/Java-programming-language/How-does-AtomicLong-lazySet-work Jackson Davis说:为一 ...
随机推荐
- ubuntu16上传文件到服务器
用windows时候,上传文件到服务器,一般都是用xshell和xftp配合使用,用ubuntu就不需要额外安装任何软件了.只用ctrl+alt+t,打开命令行用一句话就可以上传了. 将本地war包上 ...
- 转载: Linux 操作系统挂起、休眠、关机相关命令
最近每天的工作都难以在当天结束,而本人又不是那种善于熬夜的人,因此就需要将电脑中的工作文件全部保存,以往都是将所有工作文件保存关机,但是最近发现Linux系统有一个好神奇的命令: 休眠: sudo p ...
- 【linux基础】ubuntu如何查看linux的内核版本和系统版本
参考 1.查看linux内核和系统版本: 完
- vector类转换Mat类
前言 一个个数据push back到vector之后,可以使用Mat()函数将vector类型转换为Mat类型. 在opencv中Mat类的构造函数中有一个构造函数可以直接把vector类转换为Mat ...
- HDU 4632 区间DP 取模
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4632 注意到任意一个回文子序列收尾两个字符一定是相同的,于是可以区间dp,用dp[i][j]表示原字 ...
- from表单的分向提交
一:需求: 思路:document.form.action,表单分向提交,javascript提交表单同一个表单可以根据用户的选择,提交给不同的后台处理程序.即,表单的分向提交.如,在编写论坛程序时, ...
- UVa 10410 树重建
Tree Reconstruction Problem Description You have just finished a compiler design homework question w ...
- socat 简单试用
socat的主要特点就是在两个数据流之间建立通道:且支持众多协议和链接方式: ip, tcp, udp, ipv6, pipe,exec,system,open,proxy,openssl,socke ...
- Linux 安装Jdk、mysql、apache、php、tomcat、nginx
Jdk 安装分三步:第一步,上传跟 linux 位数相同的 jdk tar 包,解压:第二步:解压 tar 包,配置环境变量,且 source 一下 /etc/profile:第三步:检查版本 第一步 ...
- python之 数据类型判定与类型转换
一. 判断数据类型 0.type(x)type()可以接收任何东西作为参数――并返回它的数据类型.整型.字符串.列表.字典.元组.函数.类.模块,甚至类型对象都可以作为参数被 type 函数接受. & ...