Lock on static object - Threading Question (long) [modified]
-
Hello, Recently I have been looking into threading in .NET, specifically in C#. I think I understand the necessity of using the Monitor class (or the lock statement as a shortcut) to assure that reading and writing operations on shared data are thread-safe. I am confused, however, about using the
lock
keyword onstatic
and non-static
objects, especially when the variable whose thread-safety I want to assure is in a class. This is a rather vague question, so here is some code to clarify:class MyClass { private readonly object locker; private String strToProtect; public String StringToProtect { get { lock(locker) { return strToProtect; } } set { lock(locker) { strToProtect = value; } } } private int anotherPrivateObject; public void ThreadFunction() { anotherPrivateObject = 0; for(int i = 0; i < 10; i++) { anotherPrivateObject++; System.Threading.Thread.Sleep(100); System.Diagnostics.Trace(StringToProtect); } } } ... Main() { MyClass instanceObject = new MyClass(); instanceObject.StringToProtect = "set the string on this instance of MyClass"; Thread myThread = new Thread(new ThreadStart(instanceObject.ThreadFunction)); myThread.Start(); instanceObject.StringToProtect = "changing this string should not be a problem"; ... }
Now my questions about this code are these: 1) Is this a proper way to lock an object inside a class and access it by multiple threads? (i.e. always going through
StringToProtect
's public accessor?) 2) Shouldlocker
bestatic
? If so, why? I think this question mainly arises from confusion about thestatic
keyword - this confusion mainly arose from my recent investigation of threading, because many (if not all) of the examples I have seen use astatic
object to lock on. Those two questions are the most important, but a third one occurs to me as well: 3) Is it wrong or bad-practice to have a thread function inside a class which is not astatic
function itself? Like, in my code example, the functionMyClass.ThreadFunction
. Is it a problem that this is not astatic
function and therefore can only be called when alread -
Hello, Recently I have been looking into threading in .NET, specifically in C#. I think I understand the necessity of using the Monitor class (or the lock statement as a shortcut) to assure that reading and writing operations on shared data are thread-safe. I am confused, however, about using the
lock
keyword onstatic
and non-static
objects, especially when the variable whose thread-safety I want to assure is in a class. This is a rather vague question, so here is some code to clarify:class MyClass { private readonly object locker; private String strToProtect; public String StringToProtect { get { lock(locker) { return strToProtect; } } set { lock(locker) { strToProtect = value; } } } private int anotherPrivateObject; public void ThreadFunction() { anotherPrivateObject = 0; for(int i = 0; i < 10; i++) { anotherPrivateObject++; System.Threading.Thread.Sleep(100); System.Diagnostics.Trace(StringToProtect); } } } ... Main() { MyClass instanceObject = new MyClass(); instanceObject.StringToProtect = "set the string on this instance of MyClass"; Thread myThread = new Thread(new ThreadStart(instanceObject.ThreadFunction)); myThread.Start(); instanceObject.StringToProtect = "changing this string should not be a problem"; ... }
Now my questions about this code are these: 1) Is this a proper way to lock an object inside a class and access it by multiple threads? (i.e. always going through
StringToProtect
's public accessor?) 2) Shouldlocker
bestatic
? If so, why? I think this question mainly arises from confusion about thestatic
keyword - this confusion mainly arose from my recent investigation of threading, because many (if not all) of the examples I have seen use astatic
object to lock on. Those two questions are the most important, but a third one occurs to me as well: 3) Is it wrong or bad-practice to have a thread function inside a class which is not astatic
function itself? Like, in my code example, the functionMyClass.ThreadFunction
. Is it a problem that this is not astatic
function and therefore can only be called when alreadI don't see anything wrong with what you're doing. You use the property correctly by locking access to your field
strToProtect
. The lock object should be static if the field you're trying to lock is also static, but your field is an instance variable. And your thread function doesn't need to be static. It's not bad practice, it's just depends on what your requirements demand. As an instance method, that method will have access to the particular instance ofMyClass
. If you want any of these things to be static, you should make them all static: the field, the lock object, and the thread method. HTH -
I don't see anything wrong with what you're doing. You use the property correctly by locking access to your field
strToProtect
. The lock object should be static if the field you're trying to lock is also static, but your field is an instance variable. And your thread function doesn't need to be static. It's not bad practice, it's just depends on what your requirements demand. As an instance method, that method will have access to the particular instance ofMyClass
. If you want any of these things to be static, you should make them all static: the field, the lock object, and the thread method. HTHDustin, Thank you for the prompt response, that solves my difficulty! Sincerely, Alexander Wiseman
-
Hello, Recently I have been looking into threading in .NET, specifically in C#. I think I understand the necessity of using the Monitor class (or the lock statement as a shortcut) to assure that reading and writing operations on shared data are thread-safe. I am confused, however, about using the
lock
keyword onstatic
and non-static
objects, especially when the variable whose thread-safety I want to assure is in a class. This is a rather vague question, so here is some code to clarify:class MyClass { private readonly object locker; private String strToProtect; public String StringToProtect { get { lock(locker) { return strToProtect; } } set { lock(locker) { strToProtect = value; } } } private int anotherPrivateObject; public void ThreadFunction() { anotherPrivateObject = 0; for(int i = 0; i < 10; i++) { anotherPrivateObject++; System.Threading.Thread.Sleep(100); System.Diagnostics.Trace(StringToProtect); } } } ... Main() { MyClass instanceObject = new MyClass(); instanceObject.StringToProtect = "set the string on this instance of MyClass"; Thread myThread = new Thread(new ThreadStart(instanceObject.ThreadFunction)); myThread.Start(); instanceObject.StringToProtect = "changing this string should not be a problem"; ... }
Now my questions about this code are these: 1) Is this a proper way to lock an object inside a class and access it by multiple threads? (i.e. always going through
StringToProtect
's public accessor?) 2) Shouldlocker
bestatic
? If so, why? I think this question mainly arises from confusion about thestatic
keyword - this confusion mainly arose from my recent investigation of threading, because many (if not all) of the examples I have seen use astatic
object to lock on. Those two questions are the most important, but a third one occurs to me as well: 3) Is it wrong or bad-practice to have a thread function inside a class which is not astatic
function itself? Like, in my code example, the functionMyClass.ThreadFunction
. Is it a problem that this is not astatic
function and therefore can only be called when alread -
Thanks for the reference! Among other snippets, I had been looking at this[^] excellent article, by Jon Skeet. Because of the way he does the code snippets, though, I got confused about locking on non-
static
objects (almost all his samples havestatic
locking objects, though he does make reference tostatic
vs. non-static
in one place in the article). His Miscellanous Utility library[^] is also extremely useful (he provides a class that gives you the ability to have locks with timeouts). Thanks again. Sincerely, Alexander Wiseman