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();
            }
    
    }
  • 相关阅读:
    mysql数据库常用指令
    解决windows的mysql无法启动 服务没有报告任何错误的经验。
    “Can't open file for writing”或“operation not permitted”的解决办法
    启动Apache出现错误Port 80 in use by "Unable to open process" with PID 4!
    如何打开windows的服务services.msc
    常见的HTTP状态码 404 500 301 200
    linux系统常用的重启、关机指令
    (wifi)wifi移植之命令行调试driver和supplicant
    linux(debian)安装USB无线网卡(tp-link TL-WN725N rtl8188eu )
    alloc_chrdev_region申请一个动态主设备号,并申请一系列次设备号
  • 原文地址:https://www.cnblogs.com/lenmom/p/10042810.html
Copyright © 2011-2022 走看看