Using C # lock keyword

I will explain my understanding of C # blocking as follows, please help me check if I understand this correctly.

public class TestLock { private object threadLock = new object(); ... public void PrintOne() { lock (threadLock) { // SectionOne } } public void PrintTwo() { lock (threadLock) { // SectionTwo } } ... } 

Case I> Thread1 and Thread2 simultaneously try to call PrintOne. Since PrintOne is protected by instance locking, at any time, only one thread can go exclusively to the One section.

Is it correct?

Case II> Thread1 and Thread2 simultaneously try to call PrintOne and PrintTwo, respectively (i.e. Thread1 calls PrintOne and Thread2 calls PrintTwo) Since the two printing methods are protected by the same instance lock at any time, only one thread can exclusively access the section SectionOne or SectionTwo, but NOT both.

Is it correct?

+8
multithreading c # locking
source share
6 answers

1 and 2 are true only if all of your threads use the same instance of the class. If they use different instances , then both cases: false

Example

 public class TestLock { private object threadLock = new object(); public void PrintOne() { lock (threadLock) { Console.WriteLine("One"); var f = File.OpenWrite(@"C:\temp\file.txt"); //same static resource f.Close(); } } public void PrintTwo() { lock (threadLock) { Console.WriteLine("Two"); var f = File.OpenWrite(@"C:\temp\file.txt"); //same static resource f.Close(); } } } 

And the test code

 static void Main(string[] args) { int caseNumber = 100; var threads = new Thread[caseNumber]; for (int i = 0; i < caseNumber; i++) { var t = new Thread(() => { //create new instance var testLock = new TestLock(); //for this instance we safe testLock.PrintOne(); testLock.PrintTwo(); }); t.Start(); //once created more than one thread, we are unsafe } } 

One possible solution is to add a static keyword to the declaration of the lock object and the methods that use it.

 private static object threadLock = new object(); 

UPDATE Good moment made by konrad.kruczynski

... "thread safety" is also taken from context. For example, I could take the file open code, and also throw an exception with a static lock - just by taking another domain application. And therefore, we suggest that the OP should use the system-wide Mutex class or this. Therefore, the static case is simply displayed as an instance.

+6
source share

Yes and yes. The cases are true.

+1
source share

Case I: Check βœ“

Case II: Check βœ“

Remember that blocking is just one way to synchronize threads. For other custom methods read: Thread Synchronization

Straight from the MSDN sample:

 public class TestThreading { private System.Object lockThis = new System.Object(); public void Process() { lock (lockThis) { // Access thread-sensitive resources. } } } 
+1
source share

Your understanding is 100% correct. So, if, for example, you wanted to allow the entrance to the two methods separately, you would like to have two locks.

+1
source share

Yes, you are right in both cases.

0
source share

Here is the basic information (more or less)

1) use instance locks for instance data

 public class InstanceOnlyClass{ private int callCount; private object lockObject = new object(); public void CallMe() { lock(lockObject) { callCount++; } } } 

2) use static locks for static data

 public class StaticOnlyClass{ private int createdObjects; private static object staticLockObject = new object(); public StaticOnlyClass() { lock(staticLockObject) { createdObjects++; } } } 

3) if you protect static data and instance data, use separate static and instance locks

 public class StaticAndInstanceClass{ private int createdObjects; private static object staticLockObject = new object(); private int callCount; private object lockObject = new object(); public StaticAndInstanceClass() { lock(staticLockObject) { createdObjects++; } } public void CallMe() { lock(lockObject) { callCount++; } } } 

based on this, your code is good if you are accessing instance data, but unsafe if you are modifying static data

0
source share

All Articles