What is does
A little known feature of .NET is the synchronized keyword. The keyword can be used on methods and it ensures:
- Instance method – can be executed in a single thread on the instance (different instances are not synchronized). Equivalent to lock(this).
- Static method – can be executed in a single thread. Equivalent to lock(typeof(TypeName)).
Usage in C#
If you’ll look at the C# specification you’ll see that there’s no mention of this keyword. The reason is that the keyword is an IL keyword and not a C# one. In order to instruct the compiler to mark the method as synchronized, we can use the MethodImplAttibute with Synchronized MethodImplOptions. For example:
public void MethodWithSyncAttribute()
The IL result
Using synchronized keyword
The MethodWithSyncAttribute() looks in IL:
.method public hidebysig instance void MethodWithSyncAttribute() cil managed synchronized
// Code size 2 (0x2)
It is very clear that this method has no explicit lock instructions like Monitor.Enter for example. Yet, it’ll still behave the same as if we had used a lock block around the method body.
Using lock block
The previous method is equivalent to the next:
public void MethodWithExplicitLock()
This method translates into:
.method public hidebysig instance void MethodWithExplicitLock() cil managed
// Code size 36 (0x24)
.locals init ( bool ‘s__LockTaken0’,
 class Sync.Logger CS$2$0000,
 bool CS$4$0001)
IL_0006: ldloca.s ‘s__LockTaken0’
IL_0008: call void [mscorlib]System.Threading.Monitor::Enter(object,
IL_0010: leave.s IL_0022
} // end .try
IL_0018: brtrue.s IL_0021
IL_001b: call void [mscorlib]System.Threading.Monitor::Exit(object)
} // end handler
As can be seen, the lock block translates naturally into a try/finally block with calls to Montior.Enter and Monitor.Leave.
The synchronized keyword is an IL keyword that synchronizes the marked method calls. It causes the method to behave in an equivalent way to the one where the whole body is surrounded with lock block. It is interesting to note that locking instructions are generated only during JIT when using the keyword.
The bottom line is that for C# developers it mostly provides another syntactic sugar for defining trivial lock.