zoukankan      html  css  js  c++  java
  • 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>0</c>.
            /// </summary>
            public AtomicLong()
                : this(0) {
    
            }
    
            /// <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(1);
            }
    
            /// <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(-1);
        }
    
            /// <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();
            }
    
    }
  • 相关阅读:
    一文让你快速入门pytest框架
    Python classmethod 修饰符
    python三种导入模块的方法
    18 | 眼前一亮:带你玩转GUI自动化的测试报告
    20193103《Python程序设计》实验二报告
    20193103陈柏维《Python程序设计》实验四报告
    20193103《Python程序设计》实验三报告
    20193103陈柏维《Python程序设计》实验一报告
    一种有效的编程思路
    一些希望实现的项目
  • 原文地址:https://www.cnblogs.com/lenmom/p/10042810.html
Copyright © 2011-2022 走看看