Question on parameter for thread monitor?

  • Thread starter Thread starter brett
  • Start date Start date
B

brett

What exactly is the parameter passed to a thread monitor used for?

For example, I might do this:

private Object Protect1 = new object();

Monitor.Enter(this.Protect1);
try
{
myarray[j].Delete();
}
finally
{
Monitor.Enter(this.Protect1);
}

The Protect1 parameter has nothing to do with my logic. Yet if I leave
it out, I get this error:
No overload for method 'Enter' takes '0' arguments

Is the parameter just the name of my code block? Meaning, what ever I
have in the enter part must correspond with what I have in the exit
part?

Thanks,
Brett
 
If I need four locks in the same class, do I need to pass in the same
object or use four different objects?

Declaring these objects as static gives this error:
Static member 'mynamespace.myclass.Protect1' cannot be accessed with an
instance reference; qualify it with a type name instead

What does the above mean?

Thanks,
Brett
 
brett said:
If I need four locks in the same class, do I need to pass in the same
object or use four different objects?

If you want to actually have four different locks, you need four
different objects. If you want four sections of code where no two
threads can be in *any* of the sections at the same time, you need a
single lock object.
Declaring these objects as static gives this error:
Static member 'mynamespace.myclass.Protect1' cannot be accessed with an
instance reference; qualify it with a type name instead

What does the above mean?

It's like trying to call a static method with a variable, eg

Thread t = new Thread();
t.Sleep(5000);

C# (fortunately) doesn't let you do that. You're trying to do the same
thing, but with a field or property instead.
 
I don't follow your last example. The thead syntax is correct except
you don't have a pointer to the method via new ThreadStart(). Yet you
say the code is incorrect. Please elaborate possibly with a different
example.

Please give an example of this and why it doesn't work: "It's like
trying to call a static method with a variable"?

Thanks,
Brett
 
brett said:
I don't follow your last example. The thead syntax is correct except
you don't have a pointer to the method via new ThreadStart(). Yet you
say the code is incorrect.

It is indeed. The syntax is *not* correct, because it calls a static
method (Thread.Sleep) via an instance reference.
Please elaborate possibly with a different example.

Sure:

string x = "hello";

string y = x.Concat("a", "b");
Please give an example of this and why it doesn't work: "It's like
trying to call a static method with a variable"?

It doesn't work because the C# language forbids static members to be
referenced as if they were instance members. This prevents subtle bugs.
For instance, using the Thread.Sleep example I used before, the
equivalent code in VB.NET would be valid - but it would always make the
currently executing thread sleep, not the one referenced by the
variable, contrary to what the code makes it look like.
 
t.sleep() should calling the instance and not the static right? There
is the option of making a specific thread sleep. t being the instance
of some particular thread and t.sleep() belonging to that instance. I
do see what you mean by Thread.sleep() invoking on the current thread.

You still confuse me with why you believe the thread syntax is
incorrect. It isn't calling the static sleep(). It's calling the one
on the instance of t.
 
brett said:
t.sleep() should calling the instance and not the static right?

But there *isn't* an instance method.
There is the option of making a specific thread sleep.

No there isn't.
t being the instance of some particular thread and t.sleep()
belonging to that instance.

There is no instance method called Sleep in the Thread class. If you
don't believe me, try it :)
I do see what you mean by Thread.sleep() invoking on the current
thread.

You still confuse me with why you believe the thread syntax is
incorrect. It isn't calling the static sleep(). It's calling the one
on the instance of t.

Please just try it. I'll be very impressed if you can produce a short
program which demonstrates making a different thread sleep using the
Sleep method.

Did you understand the String.Concat example? The principle is exactly
the same, just with the Thread class.
 
For my example, should I change my code from:


private Object Protect1 = new Object();
Monitor.Enter(this.Protect1);

private static Object Protect1;
Monitor.Enter(Protect1);

Thanks,
Brett
 
brett said:
For my example, should I change my code from:

private Object Protect1 = new Object();
Monitor.Enter(this.Protect1);


private static Object Protect1;
Monitor.Enter(Protect1);

Yes - or change Protect1 to not be static.
 
brett said:
What is the advantage/disadvantage of it not being static in this case?

Well, if it's static, you'll have one lock, regardless of how many
instances of the class you create. Do you want to stop different
threads running the protected block of code, even if they're operating
on different instances?

Usually static locks protect access to static data, and instance locks
protect access to instance data.
 
Very good explanation. Thanks.

BTW, I checked your site but didn't see any mention of your MVP. I'd
like to discuss how you got that. Maybe in private email?
 
I should actually use:
private static Object Protect1 = new Object();

rather than
private static Object Protect1;

Otherwise I get a compile error because Protect1 hasn't been
initialized. In the latter example, Protect1 is actually null. Do
you have any comments here?

I checked your website also. Nice stuff there. I didn't see any
discussion on your MVP. I'd like to know how that came
about...possibly via private email?
 
brett said:
Very good explanation. Thanks.

BTW, I checked your site but didn't see any mention of your MVP. I'd
like to discuss how you got that. Maybe in private email?

Sure - email me at (e-mail address removed).
 
brett said:
I should actually use:
private static Object Protect1 = new Object();

rather than
private static Object Protect1;

Otherwise I get a compile error because Protect1 hasn't been
initialized. In the latter example, Protect1 is actually null. Do
you have any comments here?

Yes - the second way is definitely the way to go. In fact, I suggest
you take it one step further and make the field readonly.
 
What benefit is there to making it read only since it is never assigned
anything? Are you just referring to the off chance some other
developer unknowingly tries to give it a value?

On the static methods, if I create a string method that accepts a
string and prepends a character to it then returns the new string,
should the method be static? The method will be used application wide.
I'm thinking it should not be static because which ever class calls
the method needs integrity that its own string is not overwritten by
another method, which I'd think static would do. Please clarify what
goes on in both scenarios.

Also, I'm thinking string builder should be used in the method rather
than something like
newString = "c" + somestring;

Thanks,
Brett
 
brett said:
What benefit is there to making it read only since it is never assigned
anything? Are you just referring to the off chance some other
developer unknowingly tries to give it a value?

Yes. It ensures that it's never written to. It's possible that the JIT
can benefit from that too.
On the static methods, if I create a string method that accepts a
string and prepends a character to it then returns the new string,
should the method be static?

Yes, I would make it static.
The method will be used application wide.
I'm thinking it should not be static because which ever class calls
the method needs integrity that its own string is not overwritten by
another method, which I'd think static would do. Please clarify what
goes on in both scenarios.

Unless there's shared, changing data, it should be fine.
Also, I'm thinking string builder should be used in the method rather
than something like
newString = "c" + somestring;

No. The above would be more efficient than using a StringBuilder. You
only need to use a StringBuilder when you would otherwise have
temporary strings which you don't really need.
 
Back
Top