4
A
回答
4
lock
锁定整个块。由于它后面没有花括号({}
),所以它锁定了一个隐含块 - if
语句。在这里,同样的逻辑适用 - 如果条件满足,if
执行一个块。由于它后面也没有大括号,所以它隐含有一个包含单个语句的块。换句话说,给定的代码相当于:
lock (LockObject) {
if (instance == null) {
instance = Instance();
}
}
1
它锁定了所有的代码。这里{
和}
的if
只是略去。
1
if
声明包含“then”情况的声明。所以这个锁适用于两条线。
一个简单的经验法则是:如果有{
它适用,直到匹配}
,否则它适用,直到第一个;
。这并不包括所有的情况,但肯定是最常见的情况。
0
它锁定了整个声明。考虑下面的例子:
lock (LockObject)
{
if (instance == null) {
}
如果使用括号时仅锁定if
条件,那么它会导致编译器的错误,因为它没有被正确布置/匹配。
0
该代码片段锁定了两行代码。
直到if语句执行完成,LockObject才会被释放。这意味着,如果你在第2行条件为真,那么它将会在1号线
希望帮助:)
1
锁定由C#编译器转换为Monitor.Enter
和Monitor.Exit
释放锁之前执行第3。此C#代码
static void Main(string[] args)
{
lock (LockObject)
if (instance == null)
instance = Instance();
Console.WriteLine(instance == null);
}
,给出以下的IL代码,这清楚地表明,Monitor.Exit
(L_0036)instance
被分配(L_0026)之后被调用。
两行代码都被锁定。
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 2
.locals init (
[0] bool flag,
[1] object obj2,
[2] bool flag2)
L_0000: nop
L_0001: ldc.i4.0
L_0002: stloc.0
L_0003: ldsfld object TestLock.Program::LockObject
L_0008: dup
L_0009: stloc.1
L_000a: ldloca.s flag
L_000c: call void [mscorlib]System.Threading.Monitor::Enter(object, bool&)
L_0011: nop
L_0012: ldsfld object TestLock.Program::instance
L_0017: ldnull
L_0018: ceq
L_001a: ldc.i4.0
L_001b: ceq
L_001d: stloc.2
L_001e: ldloc.2
L_001f: brtrue.s L_002b
L_0021: call object TestLock.Program::Instance()
L_0026: stsfld object TestLock.Program::instance
L_002b: leave.s L_003d
L_002d: ldloc.0
L_002e: ldc.i4.0
L_002f: ceq
L_0031: stloc.2
L_0032: ldloc.2
L_0033: brtrue.s L_003c
L_0035: ldloc.1
L_0036: call void [mscorlib]System.Threading.Monitor::Exit(object)
L_003b: nop
L_003c: endfinally
L_003d: nop
L_003e: ldsfld object TestLock.Program::instance
L_0043: ldnull
L_0044: ceq
L_0046: call void [mscorlib]System.Console::WriteLine(bool)
L_004b: nop
L_004c: ret
.try L_0003 to L_002d finally handler L_002d to L_003d
}
2
if
声明不能单独执行,它需要块后,为表达true
- 案例,因此,作为@Mureinik已经说过,lock
锁定整个初始化块。你甚至可以把它写这样的:
lock (LockObject) if (instance == null) instance = Instance();
然而,这不建议写你的代码,而在这种情况下,大括号,因为它是非常混乱,难以调试。还要注意的是lock
语句是一个语法糖Monitor
类的使用,你的代码被编译成这样:
try
{
Monitor.Enter(LockObject);
if (instance == null)
{
instance = Instance();
}
}
finally
{
Monitor.Exit(LockObject);
}
而且我要注意,初始化逻辑你可以使用一个Lazy<T>
类,它是线程 - 安全,并没有使用像Monitor
那么重的构造,并且可以比你的代码更快地执行。代码将是这样的:
// field in class
Lazy<Instance> lazyInstance = new Lazy<Instance>(() => Instance());
//usage in code
var instanceValue = lazyInstance.Value;
相关问题
- 1. c#锁定语句性能
- 2. 将单行if语句拆分为多行if语句
- 3. 单行if语句 - Python的
- 4. Rails单行if else语句
- 5. C++ if语句
- 6. C++ if语句
- 7. c#if语句&& ||
- 8. C++ If/else if语句
- 9. 麻烦if if语句C++
- 10. “Dynamic”if语句C++
- 11. C++ if ... then语句
- 12. C#short if语句
- 13. objective-c if语句
- 14. c#if else语句
- 15. C#if语句dropdownlist.selectedvalue
- 16. if语句为C++
- 17. C++:在IF语句
- 18. 定期if语句
- 19. if语句行动
- 20. C#if语句范围内的语句
- 21. Beginner C++ Help:if语句中的if语句
- 22. C#asp.net if语句短,多条语句
- 23. C#中的“锁定”语句耗时吗?
- 24. ASH if if语句中的if语句
- 25. PHP IF语句中的IF IF语句
- 26. 多行宏(C++)中的If-else语句
- 27. 在MSSQL中转换单行if语句
- 28. 单行if-else语句期待keyword_do
- 29. 在string.format中添加单行if语句
- 30. Resharper格式化为单行if语句
目前它甚至不会编译,因为缺少分号。 – Filburt
或者,您可以使用'懒惰的',它更清楚地显示您的意图,并且它是线程安全的。 –