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的更多相关文章

  1. Java多线程系列--“JUC原子类”02之 AtomicLong原子类

    概要 AtomicInteger, AtomicLong和AtomicBoolean这3个基本类型的原子类的原理和用法相似.本章以AtomicLong对基本类型的原子类进行介绍.内容包括:Atomic ...

  2. AtomicLong

    Spring package com.uniubi.management.controller; import java.util.concurrent.atomic.AtomicLong; impo ...

  3. 多线程爬坑之路-J.U.C.atomic包下的AtomicInteger,AtomicLong等类的源码解析

    Atomic原子类:为基本类型的封装类Boolean,Integer,Long,对象引用等提供原子操作. 一.Atomic包下的所有类如下表: 类摘要 AtomicBoolean 可以用原子方式更新的 ...

  4. [JDK8]性能优化之使用LongAdder替换AtomicLong

    如果让你实现一个计数器,有点经验的同学可以很快的想到使用AtomicInteger或者AtomicLong进行简单的封装. 因为计数器操作涉及到内存的可见性和线程之间的竞争,而Atomic***的实现 ...

  5. JDK1.8 LongAdder 空间换时间: 比AtomicLong还高效的无锁实现

    我们知道,AtomicLong的实现方式是内部有个value 变量,当多线程并发自增,自减时,均通过CAS 指令从机器指令级别操作保证并发的原子性. // setup to use Unsafe.co ...

  6. java多线程之AtomicLong与LongAdder

    AtomicLong简要介绍 AtomicLong是作用是对长整形进行原子操作,显而易见,在java1.8中新加入了一个新的原子类LongAdder,该类也可以保证Long类型操作的原子性,相对于At ...

  7. 使用AtomicLong,经典银行账户问题

    1.新建Account类,使用AtomicLong定义账户余额,增加和减少金额方法使用getAndAdd方法. package com.xkzhangsan.atomicpack.bank; impo ...

  8. AtomicLong和LongAdder的区别

    AtomicLong的原理是依靠底层的cas来保障原子性的更新数据,在要添加或者减少的时候,会使用死循环不断地cas到特定的值,从而达到更新数据的目的. LongAdder在AtomicLong的基础 ...

  9. 【Java多线程】AtomicLong和LongAdder

    AtomicLong简要介绍 AtomicLong是作用是对长整形进行原子操作,显而易见,在java1.8中新加入了一个新的原子类LongAdder,该类也可以保证Long类型操作的原子性,相对于At ...

  10. AtomicLong.lazySet 是如何工作的?

    原文:http://www.quora.com/Java-programming-language/How-does-AtomicLong-lazySet-work Jackson Davis说:为一 ...

随机推荐

  1. Linux下idea选择tomcat server 报错Warning the selected directory is not a valid tomcat home

    这是文件的权限问题,在tomcat的目录下执行以下代码 sudo chmod 777 -R tomcat8/ 然后再去idea中配置即可

  2. BZOJ5340: [Ctsc2018]假面【概率+期望】【思维】

    LINK 思路 首先考虑减血,直接一个dp做过去,这个部分分不难拿 然后是\(op=1\)的部分 首先因为要知道每个人被打的概率,所以需要算出这个人活着的时候有多少个人活着时概率是什么 那么用\(g_ ...

  3. CSU 1112: 机器人的指令

    1112: 机器人的指令 Submit Page          Description 数轴原点有一个机器人.该机器人将执行一系列指令,你的任务是预测所有指令执行完毕之后它的位置. ·LEFT:往 ...

  4. Python学习-终端字体高亮显示

    1.采用原生转义字符序列,对Windows有的版本不支持(比如win7),完美支持Linux 实现过程: 终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关. 转义序列是以 ...

  5. CTF之猪圈密码

    猪圈密码又称济会密码,朱高密码,是一种简单的替代密码,所以安全性很低

  6. dfs、遍历与for

    dfs实际上就是若干个递归式连续使用,从而把所有情况全部遍历的方法 首先是递归式的连用,然后注意参数的选取以及变化就行了 1.参数一般有状态参数与开关参数 最简单的dfs就是每次选择只是改变自身状态( ...

  7. elasticsearch问题解决之分片副本UNASSIGNED

    在上一篇文章中,我记录了在windows下同一台机器上搭建es集群的步骤,第二天在向集群中创建索引的时候,出现了分片副本未分配的情况(UNASSIGNED). 虽然并不影响数据的插入和查询,但是有问题 ...

  8. (研) int(*p)[10]; int *p[10]; int(*)[10]; 之间的区别

    int *p[10]; 从这个最简单的说起 p先与后面的[4]结合,说明他本质是一个数组 ,“[]”的优先级比“*”要高.p先与“[]”结合,构成一个数组的定义,数组名为p,int *修饰的是数组的内 ...

  9. nexage video asset tag

    video  ad can't show InLine  must  match   the example ,and   xml content is  Case Sensitive https:/ ...

  10. EditPLus添加到右键图文教程

    最近在研究asp听他们说EditPlus非常适合,于是下了一个,感觉还真不错,EditPlus就是一个文本编辑器,说得通俗点他和WINDOWS自带的记事本差不多,但是功能更强,一般应用于程序员编程,因 ...