471,354 Members | 1,474 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,354 software developers and data experts.

Locking techniques

To synchronize thread access to shared objects, I've always used the
lock(shared_object) { } pattern.
I've seen many recommendations and examples where to synchronize use
lock(another_object) { use shared_object; } pattern.

I do not see any reason to have another simple object to lock for since I
can lock the shared object directly.

Are there any deep implications to use shared lock object to guard the
actual shared object, maybe performance oriented?
Which is better, if it can be measured?
TIA,

LT
Nov 30 '05 #1
14 1284
Hi LT,

A recommendation to use the latter approach [lock(another_object)] is
because your code controls who and when locks are applied to to this
object. In the first case, a rogue client may obtain and keep a lock
to the shared_object preventing the other threads from accessing it.

I'm not sure if there is some code deep down in the CLR that would
impact performance and somehow I don't think so. But the latter
approach uses one more object a little more memory than the first.

In my opinion, if you are writing your own application and the
shared_object is a private object, ie no one can access it outside
you're code, then you'll be quite fine using the first approach.

In short, the second approach is safer and less error prone but uses a
bit more memory.

Cheers,
Adam
-------------------------------------------------------------------------------------------
J-Integra Interoperability Solutions
http://j-integra.intrinsyc.com/
high performance interop middleware for java, corba, com & .net

Nov 30 '05 #2
Hi Adam,

For me the first approach lock(shared_object) seemed better since I do not
need to lookup which object guards which. It's easier to remember to lock
the object I need to operate really than to lookup which guard object guards
what. And it makes locking more granular automatically because the
another_object could be used (wrongly) to guard other uses also.
I was more concerned if there could be some CLR internals that makes the
first apporach more inefficient or "dangerous".

Thanks,

LT

"Adam Cooper" <ad*********@gmail.com> ha scritto nel messaggio
news:11**********************@g49g2000cwa.googlegr oups.com...
Hi LT,

A recommendation to use the latter approach [lock(another_object)] is
because your code controls who and when locks are applied to to this
object. In the first case, a rogue client may obtain and keep a lock
to the shared_object preventing the other threads from accessing it.

I'm not sure if there is some code deep down in the CLR that would
impact performance and somehow I don't think so. But the latter
approach uses one more object a little more memory than the first.

In my opinion, if you are writing your own application and the
shared_object is a private object, ie no one can access it outside
you're code, then you'll be quite fine using the first approach.

In short, the second approach is safer and less error prone but uses a
bit more memory.

Cheers,
Adam
-------------------------------------------------------------------------------------------
J-Integra Interoperability Solutions
http://j-integra.intrinsyc.com/
high performance interop middleware for java, corba, com & .net

Dec 1 '05 #3

"Adam Cooper" <ad*********@gmail.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com...
Hi LT,

A recommendation to use the latter approach [lock(another_object)] is
because your code controls who and when locks are applied to to this
object. In the first case, a rogue client may obtain and keep a lock
to the shared_object preventing the other threads from accessing it.

I'm not sure if there is some code deep down in the CLR that would
impact performance and somehow I don't think so. But the latter
approach uses one more object a little more memory than the first.

In my opinion, if you are writing your own application and the
shared_object is a private object, ie no one can access it outside
you're code, then you'll be quite fine using the first approach.

In short, the second approach is safer and less error prone but uses a
bit more memory.

Cheers,
Adam


Also, as Singletons are often implemented with static members and methods
there are no 'this' to lock on. Hence, a lock object are needed.

Happy Coding
- Michael S
Dec 1 '05 #4
Michael S wrote:

<snip>
Also, as Singletons are often implemented with static members and methods
there are no 'this' to lock on. Hence, a lock object are needed.


In those cases, typeof(Singleton) is often used to lock on - which is
just as bad as locking on "this".

Jon

Dec 1 '05 #5
Laura T. wrote:
For me the first approach lock(shared_object) seemed better since I do not
need to lookup which object guards which.
If you don't have a *very* clear understanding about what needs to be
locked in what circumstances, you *will* run into problems.
It's easier to remember to lock
the object I need to operate really than to lookup which guard object guards
what. And it makes locking more granular automatically because the
another_object could be used (wrongly) to guard other uses also.
I was more concerned if there could be some CLR internals that makes the
first apporach more inefficient or "dangerous".


It's dangerous because if you lock on an object and some code within
the implementation of that object decides to lock on itself in another
thread, you could easily run into deadlocks when you didn't need to
have any contention in the first place.

Furthermore, if you take out locks without a clearly documented order,
you can easily deadlock even within a single class.

It sounds like you're really trying to get away from properly analysing
where you need to synchronize which resources. That's very dangerous.

See http://www.pobox.com/~skeet/csharp/lockchoice.shtml for more
information.

Jon

Dec 1 '05 #6
Is the URL correct? I get 404

Marc

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
Laura T. wrote:
For me the first approach lock(shared_object) seemed better since I do
not
need to lookup which object guards which.


If you don't have a *very* clear understanding about what needs to be
locked in what circumstances, you *will* run into problems.
It's easier to remember to lock
the object I need to operate really than to lookup which guard object
guards
what. And it makes locking more granular automatically because the
another_object could be used (wrongly) to guard other uses also.
I was more concerned if there could be some CLR internals that makes the
first apporach more inefficient or "dangerous".


It's dangerous because if you lock on an object and some code within
the implementation of that object decides to lock on itself in another
thread, you could easily run into deadlocks when you didn't need to
have any contention in the first place.

Furthermore, if you take out locks without a clearly documented order,
you can easily deadlock even within a single class.

It sounds like you're really trying to get away from properly analysing
where you need to synchronize which resources. That's very dangerous.

See http://www.pobox.com/~skeet/csharp/lockchoice.shtml for more
information.

Jon

Dec 1 '05 #7
Hi Jo,

it's not that I don't have a *very* clear understanding. To have a very
clear understanding, the rules (and parameters) must be as simple as
possibile. Thus, a rule "access to a shared x needs lock of x" seems quite
simple and clear, easier to implement than "access to shared x needs lock
y".

And yes, I agree with you for dangerous, to some extent, but as far as I go,
lock(this) is not even an issue. All objects involved are under our control.
Deadlocks can happen, granted. The simpler the rules, the simpler the lock
ordering will be to avoid catches.

Thanks!

LT

"Jon Skeet [C# MVP]" <sk***@pobox.com> ha scritto nel messaggio
news:11**********************@g47g2000cwa.googlegr oups.com...
Laura T. wrote:
For me the first approach lock(shared_object) seemed better since I do
not
need to lookup which object guards which.


If you don't have a *very* clear understanding about what needs to be
locked in what circumstances, you *will* run into problems.
It's easier to remember to lock
the object I need to operate really than to lookup which guard object
guards
what. And it makes locking more granular automatically because the
another_object could be used (wrongly) to guard other uses also.
I was more concerned if there could be some CLR internals that makes the
first apporach more inefficient or "dangerous".


It's dangerous because if you lock on an object and some code within
the implementation of that object decides to lock on itself in another
thread, you could easily run into deadlocks when you didn't need to
have any contention in the first place.

Furthermore, if you take out locks without a clearly documented order,
you can easily deadlock even within a single class.

It sounds like you're really trying to get away from properly analysing
where you need to synchronize which resources. That's very dangerous.

See http://www.pobox.com/~skeet/csharp/lockchoice.shtml for more
information.

Jon

Dec 1 '05 #8
There is a MSR publication that seems to approve the use of lock(this) in
many cases.

http://research.microsoft.com/resear...aspx?tr_id=921

LT

"Jon Skeet [C# MVP]" <sk***@pobox.com> ha scritto nel messaggio
news:11**********************@g47g2000cwa.googlegr oups.com...
Michael S wrote:

<snip>
Also, as Singletons are often implemented with static members and methods
there are no 'this' to lock on. Hence, a lock object are needed.


In those cases, typeof(Singleton) is often used to lock on - which is
just as bad as locking on "this".

Jon

Dec 1 '05 #9
Laura T. wrote:
There is a MSR publication that seems to approve the use of lock(this) in
many cases.

http://research.microsoft.com/resear...aspx?tr_id=921


Interesting that it doesn't really go into *why* that's being used
though - it seems to be used pretty much by default, ignoring the
possibility that other code will lock on the same reference.

I'm sure there are plenty of articles which use lock(this) - but there
are also articles which describe the pitfalls of such an approach.
Here's one by Jeffrey Richter:

http://msdn.microsoft.com/msdnmag/issues/03/01/NET/

Personally I think it was a mistake making all reference types have
monitors - although it's taken me a long time to come to that
conclusion. (I used to think it was a great idea, right back from when
I started Java programming.)

See http://www.pobox.com/~skeet/csharp/t...ernative.shtml for a
view on how I would have preferred things to work - and an option for
coding that way instead of using plain "lock" statements.

Jon

Dec 1 '05 #10
Marc Gravell <mg******@rm.com> wrote:
Is the URL correct? I get 404


Rats - missed out the threads part. Try this:
http://www.pobox.com/~skeet/csharp/lockchoice.shtml

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 1 '05 #11
Laura T. <laura_t@yahoodotdotcom> wrote:
it's not that I don't have a *very* clear understanding. To have a very
clear understanding, the rules (and parameters) must be as simple as
possibile. Thus, a rule "access to a shared x needs lock of x" seems quite
simple and clear, easier to implement than "access to shared x needs lock
y".
Except that you don't know what else will be using the same rules, and
thus locking x when you don't expect it to. If your class is the only
thing that knows about reference y, you know nothing else will lock on
it.
And yes, I agree with you for dangerous, to some extent, but as far as I go,
lock(this) is not even an issue. All objects involved are under our control.
So you're not using any framework classes whatsoever, that might choose
to lock on something else that they're passed?
Deadlocks can happen, granted. The simpler the rules, the simpler the lock
ordering will be to avoid catches.


You don't have complete control over the system at this stage though.

Still, if you want to go ahead with something you know is dangerous, of
course I can't stop you. Just don't say you weren't warned about what
constituted best practice :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 1 '05 #12
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote:
Marc Gravell <mg******@rm.com> wrote:
Is the URL correct? I get 404


Rats - missed out the threads part. Try this:
http://www.pobox.com/~skeet/csharp/lockchoice.shtml


I think you mean
<http://www.yoda.arachsys.com/csharp/threads/lockchoice.shtml>. <g>
Dec 1 '05 #13
I wrote:
I think you mean
<http://www.yoda.arachsys.com/csharp/threads/lockchoice.shtml>. <g>


I actually meant
<http://www.pobox.com/~skeet/csharp/threads/lockchoice.shtml>.
Dec 1 '05 #14
Cool Guy <co*****@abc.xyz> wrote:
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote:
Marc Gravell <mg******@rm.com> wrote:
Is the URL correct? I get 404


Rats - missed out the threads part. Try this:
http://www.pobox.com/~skeet/csharp/lockchoice.shtml


I think you mean
<http://www.yoda.arachsys.com/csharp/threads/lockchoice.shtml>. <g>


Doh, doh, doh, doh, doh...

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Dec 1 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Michael Chermside | last post: by
12 posts views Thread by Puvendran | last post: by
16 posts views Thread by Nid | last post: by
10 posts views Thread by McFly Racing | last post: by
15 posts views Thread by z. f. | last post: by
7 posts views Thread by Shak | last post: by
reply views Thread by XIAOLAOHU | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.