是一个字符串属性本身线程安全的? [英] Is a string property itself threadsafe?

查看:242
本文介绍了是一个字符串属性本身线程安全的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

字符串在C#中是不可变的和线程安全的。但是,当你有什么公共的getter财产?像这样的:

 公共字符串SampleProperty {
    得到;
    私人集;
}

如果我们有两个线程,第一个呼吁得到和相同的时间,二是呼吁设置,会发生什么?

恕我直言集必须做出一个锁是​​线程安全的是这样的:

 私人字符串sampleField;
私有对象threadSafer =新的对象();公共字符串SampleProperty {
    {返回this.sampleField; }
    私人集合{
        锁定(threadSafer){
            sampleField =价值;
        }
    }
 }


解决方案

大部分的答案都用的是原子,仿佛原子的变化是所有需要。他们不是,通常

这已经在评论中提到的,而不是通常的答案 - 这对我提供这个答案的唯一原因。 (大约在粗粒度锁定,让喜欢的东西附加的点,是完全有效的为好。)

通常你想读线程看到的最新的的变量/属性的值。该不受原子的保证。作为一个简单的例子,这里有一个的的办法来阻止一个线程:

 类BackgroundTaskDemo
{
    私人布尔停止=假;    静态无效的主要()
    {
        BackgroundTaskDemo演示=新BackgroundTaskDemo();
        新的Thread(demo.DoWork)。开始();
        Thread.sleep代码(5000);
        demo.stopping = TRUE;
    }    静态无效的DoWork()
    {
         而(!停)
         {
               //这里做什么
         }
    }
}

的DoWork 可能永远循环下去,尽管写的布尔变量是原子 - 没有什么可以从缓存的值停止JIT停止的DoWork 。为了解决这个问题,你要么需要锁定,使变量挥发性或使用一个明确的内存屏障。这一切都适用于字符串属性为好。

String's in C# are immutable and threadsafe. But what when you have a public getter property? Like this:

public String SampleProperty{
    get;
    private set;
}

If we have two threads and the first is calling 'get' and the second is calling 'set' at the "same" time, what will happen?

IMHO the set must made a lock to be thread-safe like this:

private string sampleField;
private object threadSafer = new object();

public String SampleProperty{
    get{ return this.sampleField; }
    private set{
        lock(threadSafer){
            sampleField = value;
        }
    }
 }

解决方案

Most of the answers are using the word "atomic" as if atomic changes are all that are needed. They're not, usually.

This has been mentioned in the comments, but not usually in the answers - that's the only reason for me providing this answer. (The point about locking at a coarser granularity, to allow things like appending, is entirely valid as well.)

Usually you want a reading thread to see the latest value of the variable/property. That isn't guaranteed by atomicity. As a quick example, here's a bad way to stop a thread:

class BackgroundTaskDemo
{
    private bool stopping = false;

    static void Main()
    {
        BackgroundTaskDemo demo = new BackgroundTaskDemo();
        new Thread(demo.DoWork).Start();
        Thread.Sleep(5000);
        demo.stopping = true;
    }

    static void DoWork()
    {
         while (!stopping)
         {
               // Do something here
         }
    }
}

DoWork may well loop forever, despite the write to the boolean variable being atomic - there's nothing to stop the JIT from caching the value of stopping in DoWork. To fix this, you either need to lock, make the variable volatile or use an explicit memory barrier. This all applies to string properties as well.

这篇关于是一个字符串属性本身线程安全的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆