我可以使用字符串作为锁中的锁吗?
lock("something")如果只有一行,我可以不加大括号的锁吗?
lock("something") foo();发布于 2011-08-04 14:57:28
1)是的,字符串(通常)是内嵌的(默认情况下是,谢谢@Eric),所以同一个"something"的任何实例都会指向同一个对象,所以你不会有问题的。这是 very 的糟糕做法,因为其他人,例如在另一个库中,可能会锁定您的字符串,因此可能会出现死锁。请参阅此处:Using string as a lock to do thread synchronization
您应该这样做:
private static readonly object mutex = new object();
lock(mutex)
{
//....
}2)是的,所有语句都是一样的。任何*你拥有的东西:
{
// One line
}可能只是
// One line*几乎任何东西,请参阅@LukeH的catch块示例,它需要大括号。
发布于 2011-08-04 21:53:19
是的,您可以使用string实例作为锁的目标。然而,有一些非常奇怪的边缘情况需要考虑。
案例1:文本与StringBuilder
在下面的示例中,这两个锁将不使用相同的string实例。这是因为文本是内嵌的,但构建的实例不是。
string a = "something";
string b = new StringBuilder().Append("some").Append("thing").ToString();
// These are different.
lock (a)
lock (b)但是,我们可以手动实例化字符串。
// These are the same.
lock (a)
lock (String.Intern(b))案例2:版本注意事项
不同版本之间对空字符串的处理方式有一些不同。
string a = String.Empty;
string b = new StringBuilder().Append(String.Empty);
// These are the same in 1.0, 1.1, 3.5, and 4.0.
// These are different in 2.0 and 3.0.
lock (a);
lock (String.Intern(b))案例3:实现的差异
微软的CLI实现并不是唯一的一个。可以想象,不同的实现表现出不同的行为,并有自己的一组警告。
案例4: CompilationRelaxations.NoStringInterning
取决于程序集是否用它修饰,以及CLR是否实际使用它(而不是忽略它),这可能会改变插入机制的行为。这是一个特别有害的问题,因为它可能意味着相同的代码根据其运行环境的不同而表现不同。
我相信还有其他我不知道的边缘情况。然而,关键是依赖string实例来实现锁定目的(或任何需要隐式假设其引用是否等价的目的)是危险的。
发布于 2011-08-04 15:05:29
乔治所写的一切都是正确的。不过,还有一个补充。无论如何,你都应该使用大括号来清楚地表明你想要在大括号中运行什么。假设你无意中写了这样的东西:
if(...)
// one line
// another line读到这一点时,您可能会认为这两行代码都将在if块中执行(一些示例使用identation来定义块)。如果你改写成
if(...)
{
// one line
}
// another line在if块中运行什么和没有运行什么是非常清楚的。
https://stackoverflow.com/questions/6937342
复制相似问题