Seeker said:
Nice link, Thanks!
Still toying around with my joke of a test program and I think I discovered
another interesting side effect of this attribute. It seems to not only lock
the current method but also any other methods marked with this attribute in
the object.
Yes, because it's taking out a lock on the "this" reference, which
isn't specific to the method.
MethodA() manipulates dataX
MethodB() manipulates dataX
MethodC() manipulates dataY
Each method has the [MethodImpl(MethodImplOptions.Synchronized)] attribute.
And I start 3 threads (one thread calls MethodA etc). I found that the order
is Thread1, Thread2 then Thread3. So it looks like Thread1 put a lock on all
three methods. If I remove the attribute from Method3 then the order changes
to Thread3, Thread1, Thread2. If I remove all the attributes the order
varies and I can get errors (trying to remove some data that doesn't exist
yet).
You're starting with the wrong concept - the idea of a method being
locked. It's not a method that's locked, it's a reference. In this
case, it's the "this" reference.
I'm starting to understand why this isn't a good thing. I think we are
better off with a more granular locking mechanism using the lock().
Yup - in your case, MethoA and MethodB would use one lock, whereas
MethodC would use another - if you really need that kind of
granularity. (It's often wise to go for a single lock even if it
doesn't give the highest performance, for the sake of memory and ease
of understanding.)
Of course, those methods probably don't need to lock for the *whole*
time they're in the method - just the time that they're manipulating
the shared data.