Is a lock object bound to the string method from different threads block execution?

I was just doing some random testing when blocking multithreaded this morning, and I strangely found that locking a private "string" in two separate instances actually blocks the execution of another thread. Please find the code below for reference.

What confuses me is that the "string" in two objects is really two separate objects, so why block the other on one block? (Note: if you replace the string with another object of a reference type, such as List, it will not block the execution of another thread, as we expected ...)

class Program { static void Main(string[] args) { Thread th = new Thread(DoWork); th.Start(); Thread th2 = new Thread(DoWork); th2.Start(); } static void DoWork() { Test importer = new Test(); importer.SyncTest(); } } public class Test { public void SyncTest() { string find = "test"; lock(find) { Console.WriteLine("thread starting..."); Thread.Sleep(4000); } } } 
+4
source share
3 answers

String constants are "interned" . This means that when you type:

 var s1 = "foo"; var s2 = "foo"; 

Both are the same instance of the string "foo". Similarly, this is the same instance when you call the method twice with a similar localized variable from different threads. This is done for performance reasons.

This is a special case, but on the other hand, you really shouldn't block rows. (I have not yet seen a situation where the ideal solution to create a new lock object is not the way - private object lockObject = new object(); )

+6
source

Literal strings in .NET: interned , so every time you use the same literal string, you actually use the same object. That way, both of your threads that reference "test" are referencing (and blocking) the same object.

Creating a new List or another type gives you a new object, so each thread blocks its own object.

+2
source

It blocks when you use a string, because all your Test classes use the same string instance. C # will intern all string literals to save memory. So this is only one instance of the string "test".

The common real-time runtime maintains string storage by maintaining a table called an interdomain pool that contains a single reference to each unique literal string declared or created programmatically in your program. Consequently, an instance of a literal string with a specific value exists only once in the system.

Thus, all instances of Test use the same object to lock.

+2
source

All Articles