线程安全是啥意思

Posted

技术标签:

【中文标题】线程安全是啥意思【英文标题】:What is mean by thread safe线程安全是什么意思 【发布时间】:2015-06-02 12:07:06 【问题描述】:

我一直在经历单例模式,但我不明白下面的代码是如何线程安全的:

public class ThreadSafeSingleton

    private ThreadSafeSingleton()
    
    

    public static ThreadSafeSingleton Instance
    
        get  return Nested.instance; 
    

    private class Nested
    
        static Nested()
        
        

        internal static readonly ThreadSafeSingleton instance = new ThreadSafeSingleton();
    

为什么这是线程安全的?

【问题讨论】:

Jon Skeet 在这里讨论这个csharpindepth.com/articles/general/singleton.aspx @kenny 谢谢这正是我们需要的...... 请注意,这是单例的“过于臃肿”的版本。 private readonly static ThreadSafeSingleton instance = new ThreadSafeSingleton(); 就足够了 【参考方案1】:

CLR 只执行一次静态构造函数。指定这样做。因此,instance 仅被初始化一次。这使得这个线程安全。

如何实现线程安全是一个实现细节。

【讨论】:

【参考方案2】:

请在下面找到线程安全单例实现的实现。

另外,你可以使用这个question 有用。它提供了不会影响性能的双重锁定线程安全性。

查找静态here的参考

找到参考here

以下代码不是线程安全的。两个不同的线程都可以评估测试 if (instance==null) 并发现它为真,然后都创建实例,这违反了单例模式。请注意,实际上在计算表达式之前可能已经创建了实例,但是内存模型不保证实例的新值将被其他线程看到,除非已经通过了合适的内存屏障。

不是线程安全的单例

// Bad code! Do not use!
public sealed class Singleton

    private static Singleton instance=null;

    private Singleton()
    
    

    public static Singleton Instance
    
        get
        
            if (instance==null)
            
                instance = new Singleton();
            
            return instance;
        
    
 

线程安全实现:

公共密封类 Singleton 私有静态单例实例 = null; private static readonly object padlock = new object();

Singleton()



public static Singleton Instance

    get
    
        lock (padlock)
        
            if (instance == null)
            
                instance = new Singleton();
            
            return instance;
        
    

这个实现是线程安全的。线程在共享对象上取出一个锁,然后在创建实例之前检查实例是否已经创建。这解决了内存屏障问题(因为锁定确保所有读取在获得锁之后逻辑发生,而解锁确保所有写入在锁释放之前逻辑发生)并确保只有一个线程会创建一个实例(因为只有一个线程一次可以在该部分代码中 - 当第二个线程进入它时,第一个线程将创建实例,因此表达式将评估为假)。不幸的是,每次请求实例时都会获取锁,因此性能会受到影响。

【讨论】:

以上是关于线程安全是啥意思的主要内容,如果未能解决你的问题,请参考以下文章

PHP中的线程安全或非线程安全是啥?

“safety”是啥意思?

线程安全Thread safety是什么意思?MT-Unsafe

如果我只想以线程安全的方式测试和设置标志,那么线程类是啥?

停止正在运行的线程的安全方法是啥?

jsp PageContext 对象的生命周期是啥——它是线程安全的吗?