cor*_*ore 14 c# concurrency multithreading synchronization
我还有点不清楚,什么时候可以锁定一些代码.我的一般经验法则是在读取或写入静态变量时将操作包装在锁中.但是当只读取静态变量时(例如,它是在类型初始化期间设置的只读),访问它不需要包含在锁定语句中,对吧?我最近看到一些代码看起来像下面的例子,它让我觉得我的多线程知识可能存在一些空白:
class Foo
{
private static readonly string bar = "O_o";
private bool TrySomething()
{
string bar;
lock(Foo.objectToLockOn)
{
bar = Foo.bar;
}
// Do something with bar
}
}
Run Code Online (Sandbox Code Playgroud)
这对我来说没有意义 - 为什么会出现读取寄存器的并发问题?
此外,这个例子提出了另一个问题.其中一个比另一个好吗?(例如两个持有锁的时间较短?)我想我可以拆卸MSIL ......
class Foo
{
private static string joke = "yo momma";
private string GetJoke()
{
lock(Foo.objectToLockOn)
{
return Foo.joke;
}
}
}
Run Code Online (Sandbox Code Playgroud)
与
class Foo
{
private static string joke = "yo momma";
private string GetJoke()
{
string joke;
lock(Foo.objectToLockOn)
{
joke = Foo.joke;
}
return joke;
}
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*lls 23
由于您编写的代码都没有在初始化后修改静态字段,因此不需要任何锁定.只是用新值替换字符串也不需要同步,除非新值取决于读取旧值的结果.
静态字段不是唯一需要同步的东西,任何可以修改的共享引用都容易受到同步问题的影响.
class Foo
{
private int count = 0;
public void TrySomething()
{
count++;
}
}
Run Code Online (Sandbox Code Playgroud)
您可能会认为执行TrySomething方法的两个线程没问题.但事实并非如此.
所以,即使我们两次调用count ++,count的值也只是从0变为1.让代码线程安全:
class Foo
{
private int count = 0;
private readonly object sync = new object();
public void TrySomething()
{
lock(sync)
count++;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当线程A被中断时,线程B不会弄乱计数,因为它将触及锁定语句然后阻塞,直到线程A释放同步.
顺便说一下,有一种替代方法可以使Int32s和Int64s增加线程安全性:
class Foo
{
private int count = 0;
public void TrySomething()
{
System.Threading.Interlocked.Increment(ref count);
}
}
Run Code Online (Sandbox Code Playgroud)
关于你问题的第二部分,我想我会选择哪个更容易阅读,任何性能差异都可以忽略不计.早期优化是万恶之源等.
| 归档时间: |
|
| 查看次数: |
8843 次 |
| 最近记录: |