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. python3.6 django2.06 使用QQ邮箱发送邮件

    开通QQ邮箱IMAP/SMTP服务,忘记了,重新开通一下,记住密码串. import smtplib from email.mime.text import MIMEText # 收件人列表 mail ...

  2. 安装SharePoint Server的主机重命名

    今天我头脑一热, 把安装在WS 2008 R2上的有Stand-alone SharePoint Server 2010的机器重命名了一下, 结果SharePoint Central Admin都进不 ...

  3. Softmax回归介绍

    把输入值当成幂指数求值,再正则化这些结果值.这个幂运算表示,更大的证据对应更大的假设模型(hypothesis)里面的乘数权重值.反之,拥有更少的证据意味着在假设模型里面拥有更小的乘数系数.假设模型里 ...

  4. C#使用zookeeper

    C#使用zookeeper https://blog.csdn.net/XuWei_XuWei/article/details/80611659 1.简述 zookeeper适用于分布式锁,配置管理, ...

  5. Arpa’s obvious problem and Mehrdad’s terrible solution 思维

    There are some beautiful girls in Arpa’s land as mentioned before. Once Arpa came up with an obvious ...

  6. jsp内置对象request 和response

    1.request对象主要用于处理客户端的请求 request对象常用方法 一.String  request.getParameter(String name)             根据页面表单 ...

  7. test20181016 B君的第一题

    题意 分析 考场爆零做法 考虑位数少的一定更小,高位小的一定更少. 然后计算一定位数下不同数字的个数,然后从高到低依次确定数位. 特例:如果确定的高位的后缀出现了x,那么要把x调整到后缀去,这样一定更 ...

  8. 使用python的Paramiko模块登陆SSH

    使用python的Paramiko模块登陆SSH paramiko是用Python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. python的paramiko模块 ...

  9. /etc/inittab 学习

    1.文件内容 2.内容讲解 http://www.2cto.com/os/201108/98426.html init的进程号是1(ps -aux | less),从这一点就能看出,init进程是系统 ...

  10. php登陆绑定手机验证码使用阿里大于接口

    https://doc.alidayu.com/doc2/index.htm  一条0.045 元  新注册送10块