单身和线程安全?

时间:2017-02-26 15:00:04

标签: c# multithreading singleton

我目前正在开发一个" Singleton"类,但它必须承受线程安全,因为我不仅访问,而且设置一些东西..我想知道我怎么能这样 - 因为似乎锁定lock(object)的东西感觉有点hacky,当我不知道它实际在做什么,以及我是否必须使每一个方法线程都安全?

到目前为止,我有这个非线程安全的代码 - 因为在每个线程中应该访问相同的数据。我怎样才能最好地保证线程安全并保持单身?

public class AppSession() {
    private static AppSession _instance = new AppSession();
    public static AppSession Instance { get { return _instance; } }

    private AppSession() { }

    private string _actionName = "none";
    private DateTime? _actionTime = null;        
    public void ActionExecuted(string action) {
        _actionName = action ?? String.Empty;
        _actionTime = DateTime.UtcNow;
    }

    public LastAction {
       get { return $"{_action} at {_actionTime?.Value.ToString()}"; }
    }
}

1 个答案:

答案 0 :(得分:3)

  1. 首先,我将首先调整您的Singleton以使用.NET库中的Lazy<T>类。 “Lazy<T>提供对延迟初始化的支持”作为MSDN文档状态,它还提供a bool parameter isThreadSafe,当真实“使实例可由多个线程同时使用时”。

    private static Lazy<AppSession> _instance = 
    new Lazy<AppSession>(
        () => new LazyAppsession(), isThreadSafe: true
    );
    
  2. 其次我会将Lazy<AppSession>标记为readonly,这样任何方法或代码都无法覆盖_instance字段的值。

  3. 对于ActionExecuted方法,我不知道你是否仍然需要通过锁定它来使一个线程安全...这是我想的东西,但不要接受我的话对于它 - 我希望其他人可以扩展我的答案 - 因为我也想知道自己!
  4. 因此,你的课程看起来像这样 - 但我不确定ActionExecuted方法,正如我所说,我认识的唯一能理解这一点的人是@JonSkeet。 / p>

    public class AppSession() {
        private static readonly Lazy<AppSession> _instance = 
            new Lazy<AppSession>(
                () => new LazyAppsession(), isThreadSafe: true
            );
        public static AppSession Instance { 
            get { return _instance.Value; } 
        }
    
        private AppSession() { }
    
        private string _actionName = "none";
        private DateTime? _actionTime = null;        
        public void ActionExecuted(string action) {
            _actionName = action ?? String.Empty;
            _actionTime = DateTime.UtcNow;
        }
    }