lock statement

S

Sunny

Hi,
I can not understend completely the lock statement.
Actally what is locked:
1. the part of the code between {...}
or
2. the object in lock()

In the docs is written:
for 1: 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. lock ensures that one thread
does not enter a critical section while another thread is in the
critical section of code. If another thread attempts to enter a locked
code, it will wait (block) until the object is released.

for 2: Typically, expression will either be this, if you want to protect
an instance variable, or typeof(class), if you want to protect a static
variable (or if the critical section occurs in a static method in the
given class).

What is happening if:

public class MyClass
{
int x;

public void MyAMethod()
{
lock(this)
{
x++;
}
}

public void MyBMethod()
{
lock(this)
{
x--;
}
}

public void MyCMethod()
{
x = x*x;
}
}

Now, if I create

static MyClass myInstance = new MyClass();

and in different threads I invoke different methods of myInstance what
will happen? Will MyCMethod (without lock) change x while other thread
has a lock over the object, or will wait until lock is released?


And if I have:

public class MyClass
{
public static int[] arr;
public static int[] otherobject;
...some nonstatic methods and vars
}

if in different threads I have different instances of MyClass, and while
executing different methods, may I lock only arr?
I.e.:

Thread1:

class test1
{
MyClass inst1 = new MyClass;
public void Test1Method()
{
lock (MyClass.arr)
{ .code1. }
}
}

Thread2:

class test2
{
MyClass inst2 = new MyClass;
public void Test2Method()
{
lock (MyClass.arr)
{ .code2. }
}
}

Thread3:
class test3
{
MyClass inst3 = new MyClass;
public void Test3Method()
{
MyClass.otherobject[8] = 11;
MyClass.arr[3] = 5;
}
}

Will Test3Method wait for changing the value, while other thread release
MyClass.arr? And if so, if there are more static objects in MyClass, but
lock is only over one of them, where Test3Method will stop for waiting?


Thanks
Sunny
 
J

Jeffrey Tan[MSFT]

Hi Sunny,

the lock(this) statement use this keyword to implement mutex, so MyAMethod
and MyBMethod will visit the critical section one by one, while MyCMethod
is not
restricted by this.

you can determine this by the sample code below:

using System;
using System.Threading ;

namespace consolethread
{
public class MyClass
{
int x;
public MyClass()
{
x=1;
}

public void MyAMethod()
{
lock(this)
{
Thread.Sleep(10000);
x++;

Console.WriteLine("x after x++:"+x);
}
}

public void MyBMethod()
{
lock(this)
{
x--;
Console.WriteLine("x after x--:"+x);
}
}

public void MyCMethod()
{
x = x*x;
Console.WriteLine("x after x*x:"+x);
}
}
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
MyClass obj;
public void proc1()
{
this.obj.MyAMethod();
}

public void proc2()
{
obj.MyBMethod();
}

public void proc3()
{
obj.MyCMethod();
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
Class1 c=new Class1();
c.obj=new MyClass ();

Thread t1=new Thread(new ThreadStart(c.proc1));
Thread t2=new Thread(new ThreadStart(c.proc2));
Thread t3=new Thread(new ThreadStart(c.proc3));

t1.Start();
t2.Start ();
t3.Start();
Console.Read ();
}
}
}


As you can see in the document, if you want to lock the static variable or
in static method, you should
lock the typeof class(if you only lock the static variable it will not
work), sample code listed below:
using System;
using System.Threading;

namespace newthreadtest
{
public class MyClass
{
public static int[] arr;
public static int[] otherobject;
public MyClass()
{
arr=new int[3];
}
}

/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
public static void proc1()
{
MyClass inst1 = new MyClass();
lock (typeof(MyClass))
{
Console.WriteLine ("thread1 launched!");
Thread.Sleep(7000);
Console.WriteLine("thread1");
}

}

public static void proc2()
{

MyClass inst2 = new MyClass();

lock (typeof(MyClass))
{
Console.WriteLine("thread2");
}

}

public static void proc3()
{
MyClass inst3 = new MyClass();

//MyClass.otherobject[8] = 11;
//MyClass.arr[3] = 5;
Console.WriteLine("thread3");

}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//

Thread t1=new Thread(new ThreadStart(proc1));
Thread t2=new Thread(new ThreadStart(proc2));
Thread t3=new Thread(new ThreadStart(proc3));

t1.Start();
Thread.Sleep(1000);
t2.Start ();
t3.Start();
Console.Read ();
}
}
}

Hope this helps,

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: Sunny <[email protected]>
| Subject: lock statement
| Date: Tue, 9 Sep 2003 19:24:03 -0500
| Message-ID: <[email protected]>
| Organization: Iceberg Wireless LLC
| MIME-Version: 1.0
| Content-Type: text/plain; charset="iso-8859-15"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: MicroPlanet Gravity v2.60
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: 216.17.90.91
| Lines: 1
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP10.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:183626
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Hi,
| I can not understend completely the lock statement.
| Actally what is locked:
| 1. the part of the code between {...}
| or
| 2. the object in lock()
|
| In the docs is written:
| for 1: 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. lock ensures that one thread
| does not enter a critical section while another thread is in the
| critical section of code. If another thread attempts to enter a locked
| code, it will wait (block) until the object is released.
|
| for 2: Typically, expression will either be this, if you want to protect
| an instance variable, or typeof(class), if you want to protect a static
| variable (or if the critical section occurs in a static method in the
| given class).
|
| What is happening if:
|
| public class MyClass
| {
| int x;
|
| public void MyAMethod()
| {
| lock(this)
| {
| x++;
| }
| }
|
| public void MyBMethod()
| {
| lock(this)
| {
| x--;
| }
| }
|
| public void MyCMethod()
| {
| x = x*x;
| }
| }
|
| Now, if I create
|
| static MyClass myInstance = new MyClass();
|
| and in different threads I invoke different methods of myInstance what
| will happen? Will MyCMethod (without lock) change x while other thread
| has a lock over the object, or will wait until lock is released?
|
|
| And if I have:
|
| public class MyClass
| {
| public static int[] arr;
| public static int[] otherobject;
| ...some nonstatic methods and vars
| }
|
| if in different threads I have different instances of MyClass, and while
| executing different methods, may I lock only arr?
| I.e.:
|
| Thread1:
|
| class test1
| {
| MyClass inst1 = new MyClass;
| public void Test1Method()
| {
| lock (MyClass.arr)
| { .code1. }
| }
| }
|
| Thread2:
|
| class test2
| {
| MyClass inst2 = new MyClass;
| public void Test2Method()
| {
| lock (MyClass.arr)
| { .code2. }
| }
| }
|
| Thread3:
| class test3
| {
| MyClass inst3 = new MyClass;
| public void Test3Method()
| {
| MyClass.otherobject[8] = 11;
| MyClass.arr[3] = 5;
| }
| }
|
| Will Test3Method wait for changing the value, while other thread release
| MyClass.arr? And if so, if there are more static objects in MyClass, but
| lock is only over one of them, where Test3Method will stop for waiting?
|
|
| Thanks
| Sunny
|
 
S

Sunny

v- said:
Hi Sunny,

the lock(this) statement use this keyword to implement mutex, so MyAMethod
and MyBMethod will visit the critical section one by one, while MyCMethod
is not
restricted by this.
As you can see in the document, if you want to lock the static variable or
in static method, you should
lock the typeof class(if you only lock the static variable it will not
work), sample code listed below:
Hope this helps,
Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.


Thanks Jeffrey,
Now I see a little light at the end of the tunnel :)
So, basically, there is no way to lock a static object (I need a lock
over a DataSet) so no other thread is changing it? I have to lock the
whole class. But which class, the DataSet class, or the class in which I
have a static instance of the DataSet? And If I lock the DataSet class,
does it mean, that all objects (declared in other classes) of that type
will be also be locked?
Hmmm, it seems that I'm really stupid these days :)

Sorry, but this topic is very interesting, and I can not understand the
docs, and it is very hard for testing.

Thanks
Sunny
 
J

Jeffrey Tan[MSFT]

Hi Sunny,

The .net mutex technology is introduced to protect the variable when
multi-threading.
When many threads do operations on the shared variables(such as static
object),
you should use mutex to force these threads to access the shared variables
one by
one, not at the same time.

For you problem, you should put all your access of dataset object into a
critical section,
then you can use one of these mutex technologies(such as lock statement or
Mutex object) to protect it.

To use lock statement, I think you should lock the class which contains
the dataset variables.

Hope this helps,
Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: Sunny <[email protected]>
| Subject: RE: lock statement
| Date: Wed, 10 Sep 2003 08:35:45 -0500
| Message-ID: <[email protected]>
| References: <[email protected]>
<[email protected]>
| Organization: Iceberg Wireless LLC
| MIME-Version: 1.0
| Content-Type: text/plain; charset="iso-8859-15"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: MicroPlanet Gravity v2.60
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: 216.17.90.91
| Lines: 1
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!tk2msftngp13.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:183757
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| In article <[email protected]>, v-
| (e-mail address removed) says...
| >
| > Hi Sunny,
| >
| > the lock(this) statement use this keyword to implement mutex, so
MyAMethod
| > and MyBMethod will visit the critical section one by one, while
MyCMethod
| > is not
| > restricted by this.
| <snip>
| >
| >
| > As you can see in the document, if you want to lock the static variable
or
| > in static method, you should
| > lock the typeof class(if you only lock the static variable it will not
| > work), sample code listed below:
| > Hope this helps,
| <snip>
| >
| > Best regards,
| > Jeffrey Tan
| > Microsoft Online Partner Support
| > Get Secure! - www.microsoft.com/security
| > This posting is provided "as is" with no warranties and confers no
rights.
|
|
| Thanks Jeffrey,
| Now I see a little light at the end of the tunnel :)
| So, basically, there is no way to lock a static object (I need a lock
| over a DataSet) so no other thread is changing it? I have to lock the
| whole class. But which class, the DataSet class, or the class in which I
| have a static instance of the DataSet? And If I lock the DataSet class,
| does it mean, that all objects (declared in other classes) of that type
| will be also be locked?
| Hmmm, it seems that I'm really stupid these days :)
|
| Sorry, but this topic is very interesting, and I can not understand the
| docs, and it is very hard for testing.
|
| Thanks
| Sunny
|
 
S

Sunny

Hi Jeffry,
thanks for the reply. I have some more quetsions. I'll post them between
your posting.

v- said:
Hi Sunny,

The .net mutex technology is introduced to protect the variable when
multi-threading.
When many threads do operations on the shared variables(such as static
object),
you should use mutex to force these threads to access the shared variables
one by
one, not at the same time.
Ok, you are saying variable, but it requires to lock a class?!?!? How to
lock any particular variable, not the whole class?
For you problem, you should put all your access of dataset object into a
critical section,
then you can use one of these mutex technologies(such as lock statement or
Mutex object) to protect it.
Ok, I can do it (use that variable only in lock {}block), but if I lock
on the whole class in which that variable is declared, will other
threads change other variables of that class?
To use lock statement, I think you should lock the class which contains
the dataset variables.


Hope this helps,
Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
<snip>


I just can not fine anywhere a simple explanation of all that, like
(just as a sample):

When a lock (class) {block} is reached by one thread, it locks the
access to the class?!?!? for all other thread.

OR

When lock... the "class" is used only as flag for all other lock
statements based on it?

OR

No other thread can enter {block} while locked. (does not make much
sense)

OR

any combination of the above? Or any other explanation with simple
words.

Thanks again
Sunny
 
J

Jeffrey Tan[MSFT]

Hi Sunny,

To change a variable's value, you should use Interlocked class's related
method(such as
Increment, Decrement, Exchange). It will implement mutex on certain
variable.

There are ways of doing mutex on a block of code(note: not on a certain
variable): lock statement and mutex class

For mutex class, it will lock the code section between mutex.waitone() and
mutex.release. When other thread(or process) want to
get into the code that also is closed by this mutex object(note: must be
the same mutex object), it will be blocked.
(So it is mutexed by the mutex object)

For the lock statement, I think your puzzle must be on the static variable.
To lock static variable, as the docment said, you should lock the type of
the class that contain the static variable.
I think the function of the type of the class is the same as the mutex
object. You use
lock(type1) and lock(type2) to implement mutex between code sections in
your 2 threads, the code section
will get mutex only when the type1 and type2 is the same type. Even, the
static variables in the code section have
no relationship with the type1 and type2.

I have writen a sample code to determine this:

using System;
using System.Threading ;

namespace delthread
{
class testclass1
{
}

class testclass
{
public static int a;
public static int b;
}
class Class1
{
public static void proc1()
{
Console.WriteLine("testclass's a before lock:"+testclass.a);
lock(typeof(testclass1))
{
Console.WriteLine("in the proc1");
testclass.a++;
Thread.Sleep(6000);
}
Console.WriteLine("testclass's a after lock:"+testclass.a);
}

public static void proc2()
{
Console.WriteLine("testclass's b before lock:"+testclass.b);
lock(typeof(testclass1))
{
Console.WriteLine("in the proc2");
testclass.b++;
}
Console.WriteLine("testclass's b after lock:"+testclass.b);
}
[STAThread]
static void Main(string[] args)
{
testclass.a=1;
testclass.b=1;
Thread t1=new Thread(new ThreadStart(proc1));
Thread t2=new Thread(new ThreadStart(proc2));

t1.Start();
Thread.Sleep(1000);
t2.Start();
Console.Read ();
}
}
}

As you can see, I use type of testclass1 to lock the critical section,
while the
static variables in the section are the member of testclass, but these 2
threads
still get mutexed.

I hope I had explained clear to you, if you still have anything unclear,
please
feel free to let me know. I am glad to work with you.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

| From: Sunny <[email protected]>
| Subject: RE: lock statement
| Date: Wed, 10 Sep 2003 21:53:43 -0500
| Message-ID: <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| Organization: Iceberg Wireless LLC
| MIME-Version: 1.0
| Content-Type: text/plain; charset="iso-8859-15"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: MicroPlanet Gravity v2.60
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: c-66-41-159-114.mn.client2.attbi.com 66.41.159.114
| Lines: 1
| Path: cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!tk2msftngp13.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:183918
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Hi Jeffry,
| thanks for the reply. I have some more quetsions. I'll post them between
| your posting.
|
| In article <[email protected]>, v-
| (e-mail address removed) says...
| >
| > Hi Sunny,
| >
| > The .net mutex technology is introduced to protect the variable when
| > multi-threading.
| > When many threads do operations on the shared variables(such as static
| > object),
| > you should use mutex to force these threads to access the shared
variables
| > one by
| > one, not at the same time.
| Ok, you are saying variable, but it requires to lock a class?!?!? How to
| lock any particular variable, not the whole class?
|
| >
| > For you problem, you should put all your access of dataset object into
a
| > critical section,
| > then you can use one of these mutex technologies(such as lock statement
or
| > Mutex object) to protect it.
| Ok, I can do it (use that variable only in lock {}block), but if I lock
| on the whole class in which that variable is declared, will other
| threads change other variables of that class?
|
| >
| > To use lock statement, I think you should lock the class which
contains
| > the dataset variables.
|
|
| >
| > Hope this helps,
| > Best regards,
| > Jeffrey Tan
| > Microsoft Online Partner Support
| > Get Secure! - www.microsoft.com/security
| > This posting is provided "as is" with no warranties and confers no
rights.
| <snip>
|
|
| I just can not fine anywhere a simple explanation of all that, like
| (just as a sample):
|
| When a lock (class) {block} is reached by one thread, it locks the
| access to the class?!?!? for all other thread.
|
| OR
|
| When lock... the "class" is used only as flag for all other lock
| statements based on it?
|
| OR
|
| No other thread can enter {block} while locked. (does not make much
| sense)
|
| OR
|
| any combination of the above? Or any other explanation with simple
| words.
|
| Thanks again
| Sunny
|
 
S

Sunny

Hi Jeffrey,
not it is clear: so the class on which you lock is just used as a flag
for locking. Every lock statement, based on the flag class, will not
enter its block of statements until the lock is no released. Am I right?

Sunny
 
J

Jeffrey Tan[MSFT]

Hi Sunny,

Yes, you are right.
This can be confirmed by the sample code I pasted.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: Sunny <[email protected]>
| Subject: RE: lock statement
| Date: Thu, 11 Sep 2003 14:15:03 -0500
| Message-ID: <[email protected]>
| References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
| Organization: Iceberg Wireless LLC
| MIME-Version: 1.0
| Content-Type: text/plain; charset="iso-8859-15"
| Content-Transfer-Encoding: 7bit
| X-Newsreader: MicroPlanet Gravity v2.60
| Newsgroups: microsoft.public.dotnet.languages.csharp
| NNTP-Posting-Host: c-66-41-159-114.mn.client2.attbi.com 66.41.159.114
| Lines: 1
| Path:
cpmsftngxa06.phx.gbl!TK2MSFTNGXA06.phx.gbl!TK2MSFTNGXA05.phx.gbl!TK2MSFTNGP0
8.phx.gbl!TK2MSFTNGP09.phx.gbl
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:184185
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| Hi Jeffrey,
| not it is clear: so the class on which you lock is just used as a flag
| for locking. Every lock statement, based on the flag class, will not
| enter its block of statements until the lock is no released. Am I right?
|
| Sunny
|
|
| In article <[email protected]>, v-
| (e-mail address removed) says...
| >
| > Hi Sunny,
| >
| > To change a variable's value, you should use Interlocked class's
related
| > method(such as
| > Increment, Decrement, Exchange). It will implement mutex on certain
| > variable.
| >
| > There are ways of doing mutex on a block of code(note: not on a certain
| > variable): lock statement and mutex class
| >
| > For mutex class, it will lock the code section between mutex.waitone()
and
| > mutex.release. When other thread(or process) want to
| > get into the code that also is closed by this mutex object(note: must
be
| > the same mutex object), it will be blocked.
| > (So it is mutexed by the mutex object)
| >
| > For the lock statement, I think your puzzle must be on the static
variable.
| > To lock static variable, as the docment said, you should lock the type
of
| > the class that contain the static variable.
| > I think the function of the type of the class is the same as the mutex
| > object. You use
| > lock(type1) and lock(type2) to implement mutex between code sections in
| > your 2 threads, the code section
| > will get mutex only when the type1 and type2 is the same type. Even,
the
| > static variables in the code section have
| > no relationship with the type1 and type2.
| <snip>
| > Best regards,
| > Jeffrey Tan
| > Microsoft Online Partner Support
| > Get Secure! - www.microsoft.com/security
| > This posting is provided "as is" with no warranties and confers no
rights.
| >
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top