C# threading - Lock Object
Solution 1
You need to create a separate lock object. The problem is that you re-assign t_x inside the loop. Assuming thread b1 gets inside the loop before b2 gets to the lock statement, b2 will be allowed inside the lock statement because, by that time, t_x will be a new object that does not have a lock on it.
Solution 2
No, you can't do this - the lock block is shorthand for the following:
try(Monitor.Enter(lockObject))
{
//critical section
}
finally
{
Monitor.Exit(lockObject)
}
The documentation for Monitor.Enter states, "Use Monitor to lock objects (that is, reference types), not value types. When you pass a value type variable to Enter, it is boxed as an object. If you pass the same variable to Enter again, it is boxed as a separate object, and the thread does not block"
Solution 3
The lock (t_x) call boxes an integer as a temporary object. Each call to lock(t_x) creates a New object and locking is useless.
(Lock expects an object and creates a NEW temporary object from the integer)
Just create a seperate lock object like said above by Femaref.
Solution 4
You have to use an extra object for the lock
object lockObj = new object();
public void foo()
{
lock(lockObj)
{
//do stuff here
}
}
paul simmons
Updated on March 26, 2020Comments
-
paul simmons about 4 years
I am trying to lock a "boxed" object in a c# app, is this not possible?
class t { System.Object t_x = new object(); public t(int p) { t_x = p; } public void w() { lock (t_x) { for (int i = 0; i < 4; i++) { { t_x = ((int)t_x) + 1; Console.WriteLine(t_x); Thread.Sleep(1000); } } } } }
In another class I can start 2 threads:
Thread b1 = new Thread(new ThreadStart(t1.w)); b1.Start(); Thread b2 = new Thread(new ThreadStart(t1.w)); b2.Start();
However the portion is not locked. When I lock an arbitrary object (i.e. one created and not modified as object a=new object()) it locks well. Is boxing operation somehow "depromotes" my Object??
-
Cédric Boivin almost 15 yearsThat the good way to do it. It's in the first exam 70-536 of microsoft certification.
-
Cédric Boivin almost 15 yearsI think Monitor it's a better way to do that
-
Daniel Earwicker almost 15 years@Cedric - read Lee's answer more carefully. The
lock
statement is exactly the same as usingMonitor.Enter
andMonitor.Exit
. It's just a neater syntax for the same pattern. The issue is not whether to uselock
orMonitor
(not really a choice, as they are the same). The issue is to always pass the same object to serve as the lock, which is broken if you use a value type as it is boxed differently ever time you access it. -
Daniel Earwicker almost 15 yearsThis is the right answer - not because of the code snippet (the
lock
statement is fine) but because it mentions the difference between value and reference types. A value type is boxed again each time it is converted to the universalobject
base class, so it can't reliably act as the locking target. So this is better than the accepted answer. -
Seng Cheong about 12 yearsWhile I wouldn't recommend doing it this way (just use another
object
to lock on), I don't understand the downvotes, as it is correct.