lenmom

博客园 首页 新随笔 联系 订阅 管理
    using System;
    using System.Threading;

    /// <summary>
    /// Provides lock-free atomic read/write utility for a reference type, <c>T</c>, instance. 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>T</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>
    /// \author Matt Bolt
    public class Atomic<T> where T : class {

        private T _value;

        /// <summary>
        /// Creates a new <c>Atomic</c> instance with an initial value of <c>null</c>.
        /// </summary>
        public Atomic()
            : this(null) {

        }

        /// <summary>
        /// Creates a new <c>Atomic</c> instance with the initial value provided.
        /// </summary>
        public Atomic(T value) {
            _value = value;
        }

        /// <summary>
        /// This method returns the current value.
        /// </summary>
        /// <returns>
        /// The <c>T</c> instance.
        /// </returns>
        public T Get() {
            return _value;
        }

        /// <summary>
        /// This method sets the current value atomically.
        /// </summary>
        /// <param name="value">
        /// The new value to set.
        /// </param>
        public void Set(T 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 T GetAndSet(T 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(T expected, T result) {
            return Interlocked.CompareExchange(ref _value, result, expected) == expected;
        }

        /// <summary>
        /// This operator allows an implicit cast from <c>Atomic&lt;T&gt;</c> to <c>T</c>.
        /// </summary>
        public static implicit operator T(Atomic<T> value) {
            return value.Get();
        }

}

https://github.com/mbolt35/CSharp.Atomic

 

posted on 2018-11-30 10:44  老董  阅读(1254)  评论(0编辑  收藏  举报