-2

The docs don't explain it. They only say what should be locked on and what not.

From here it seems like the same object should be used by all threads for the lock to work. While from here it seems that that is exactly what should be avoided to prevent deadlock.

Keep in mind that I might be misunderstanding this whole matter of lock, because I just asked a question about how to "lock" a variable and got what seems to me not to achieve that at all (except locking code).

Community
  • 1
  • 1
ispiro
  • 26,556
  • 38
  • 136
  • 291
  • 1
    Don't explain *what*? "The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for *a given object*, executing a statement, and then releasing the lock." - seems pretty clear. Note the use of *object*, not *variable*, in the documentation. – user2864740 Jun 23 '14 at 20:33
  • `lock for a given object` - That. – ispiro Jun 23 '14 at 20:34
  • What isn't clear about that? A `lock` establishes mutual exclusion (when applied against the *same object*) between threads. – user2864740 Jun 23 '14 at 20:34
  • The docs that you linked to explain quite a lot more than what should and should not be locked on, including what the statement does, which is what you're asking. – Servy Jun 23 '14 at 20:36
  • 1
    Can you show the code you are trying to lock? Threading can be complex. It's hard to give you an answer other than read the answers provided in those threads. IMO- no you shouldn't lock(this){...} and then in other example the object should be as a field and not a variable again as described in the answers on that thread. It will be a lot easier to help you lock correctly with example code – Nyra Jun 23 '14 at 20:36
  • 1
    Yes, locking solves race-conditions and introduces the risk of deadlock. Win some, lose some. You'll have to use them in exactly the right way, that's why this is not a good question. Details matter. – H H Jun 23 '14 at 20:36
  • "I just asked a question about how to "lock" a variable" - You don't lock *an* object, you lock *on* an object. The code inside the lock statement is the *thing* that gets locked. I think that's the crux of your confusion. There seems to be a disconnect between your expectations and what happens. What do you expect to happen when you lock on an object? – dcastro Jun 23 '14 at 20:40
  • @dcastro Thanks. "confusion" - Yes. Exactly. That's what I thought StackOverflow was about - asking questions when one doesn't understand something. Apparently that's not the case anymore. (I'm not referring to you. Just venting. :) – ispiro Jun 23 '14 at 20:44
  • 1
    Downvotes do not have to be explained. But to give you an idea: a good question can stand on its own and is much more specific and/or detailed. It could/should have been an edit to your previous question. – H H Jun 23 '14 at 22:09
  • @ispiro One should be *precise* about questions; providing an example test-case usually helps bring about this clarity; as would extracting specific excerpts and the [read] implications of such. Otherwise, others can't tell *what* the question is really about - as in this case. – user2864740 Jun 24 '14 at 01:51

3 Answers3

4

Think of a lock as a "talking stick" that is used in some meetings. Whoever is holding the stick can talk. Anyone that wants to talk must wait until the speaker relinquishes the stick.

When a piece of code acquires a lock on an object, any other piece of code that requests a lock on that same object must wait until the original code releases the lock.

So which object should you lock? It depends greatly on the context. The rule of thumb is you lock an object that anyone else who could affect the code block can lock as well. If you're updating a collection, then you can ICollection.SyncRoot as an example.

EDIT by OP (Hopefully correct): "Anyone that wants to talk" - As the speaker "of that stick". (Anyone can just talk.) As for the second link in the question - it's referring to a problem of one lock waiting for a second, while the second is waiting for the first.

ispiro
  • 26,556
  • 38
  • 136
  • 291
D Stanley
  • 149,601
  • 11
  • 178
  • 240
3

lock should be used around any shared resource. By "shared resource" I mean anything that is accessed by more than one thread.

All a lock does is:

  1. Incoming thread wants access to a piece of code, encounters lock
  2. Lock is empty, thread is allowed in
  3. Thread gets switched out
  4. Another thread wants access to the same code (or code locked on the same variable), encounters lock
  5. Variable is already locked, thread has to wait
  6. Original thread is switched back in, exits locked code
  7. Second thread is switched back in, executes the locked code

If it is possible to have threads in a lock and waiting on another lock at the same time, that then waits on the first lock, you have a gridlock condition. Typically you don't "nest" your locks to avoid this problem. Also, for performance if nothing else, you rarely lock on the same variable as another unless you actually have both pieces relying on the code not executing concurrently (probably a bad design if it is so :) )

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • Thanks. I accepted another answer because it made it clearer for me. But your answer helped as well. +1. – ispiro Jun 23 '14 at 22:29
0

Locking something is intended to protect a piece of shared memory. So, you have to use the same SyncRoot for a specific element that you are protecting... However, say you have 3 objects that need to be protected, and they are in no way related:

A a = new A();
B b = new B();
C c = new C();

Then there is NO reason to use the same SyncRoot for all 3 of them. In fact, if they are truly separate, it would be inefficient.

poy
  • 10,063
  • 9
  • 49
  • 74