看一下以下两个例子的运行结果:
//testthread.cs
using system; using system.threading; public class test { static int count=0; static void main() { threadstart job = new threadstart(threadjob); thread thread = new thread(job); thread.start(); for (int i=0; i < 5; i++) { count++; } thread.join(); console.writeline ("final count: {0}", count); } static void threadjob() { for (int i=0; i < 5; i++) { count++; } } }
//innerdatathread.cs
using system; using system.threading; public class test { static int count=0; static void main() { threadstart job = new threadstart(threadjob); thread thread = new thread(job); thread.start(); for (int i=0; i < 5; i++) { int tmp = count; console.writeline ("read count={0}", tmp); thread.sleep(50); tmp++; console.writeline ("incremented tmp to {0}", tmp); thread.sleep(20); count = tmp; console.writeline ("written count={0}", tmp); thread.sleep(30); } thread.join(); console.writeline ("final count: {0}", count); } static void threadjob() { for (int i=0; i < 5; i++) { int tmp = count; console.writeline ("\t\t\t\tread count={0}", tmp); thread.sleep(20); tmp++; console.writeline ("\t\t\t\tincremented tmp to {0}", tmp); thread.sleep(10); count = tmp; console.writeline ("\t\t\t\twritten count={0}", tmp); thread.sleep(40); } } }
read count=0
read count=0
incremented tmp to 1
written count=1
incremented tmp to 1
written count=1
read count=1
incremented tmp to 2
read count=1
written count=2
read count=2
incremented tmp to 2
incremented tmp to 3
written count=2
written count=3
read count=3
read count=3
incremented tmp to 4
incremented tmp to 4
written count=4
written count=4
read count=4
read count=4
incremented tmp to 5
written count=5
incremented tmp to 5
written count=5
read count=5
incremented tmp to 6
written count=6
final count: 6
|
再比较下面这个例子:
//使用monitor.enter/exit
//monitorthread.cs
using system;
using system.threading;
public class test
{
static int count=0;
static readonly object countlock = new object();
static void main()
{
threadstart job = new threadstart(threadjob);
thread thread = new thread(job);
thread.start();
for (int i=0; i < 5; i++)
{
monitor.enter(countlock);
int tmp = count;
console.writeline (“read count={0}”, tmp);
thread.sleep(50);
tmp++;
console.writeline (“incremented tmp to {0}”, tmp);
thread.sleep(20);
count = tmp;
console.writeline (“written count={0}”, tmp);
monitor.exit(countlock);
thread.sleep(30);
}
thread.join();
console.writeline (“final count: {0}”, count);
}
static void threadjob()
{
for (int i=0; i < 5; i++)
{
monitor.enter(countlock);
int tmp = count;
console.writeline (“\t\t\t\tread count={0}”, tmp);
thread.sleep(20);
tmp++;
console.writeline (“\t\t\t\tincremented tmp to {0}”, tmp);
thread.sleep(10);
count = tmp;
console.writeline (“\t\t\t\twritten count={0}”, tmp);
monitor.exit(countlock);
thread.sleep(40);
}
}
}
结果与上例innerdatathread.cs是不一样的,原因就在于monitor的使用了。
read count=0
incremented tmp to 1
written count=1
read count=1
incremented tmp to 2
written count=2
read count=2
incremented tmp to 3
written count=3
read count=3
incremented tmp to 4
written count=4
read count=4
incremented tmp to 5
written count=5
read count=5
incremented tmp to 6
written count=6
read count=6
incremented tmp to 7
written count=7
read count=7
incremented tmp to 8
written count=8
read count=8
incremented tmp to 9
written count=9
read count=9
incremented tmp to 10
written count=10
final count: 10
|
下面使用lock来锁定线程:
// lockthread.cs
using system;
using system.threading;
public class test
{
static int count=0;
static readonly object countlock = new object();
static void main()
{
threadstart job = new threadstart(threadjob);
thread thread = new thread(job);
thread.start();
for (int i=0; i < 5; i++)
{
lock (countlock)
{
int tmp = count;
console.writeline (“read count={0}”, tmp);
thread.sleep(50);
tmp++;
console.writeline (“incremented tmp to {0}”, tmp);
thread.sleep(20);
count = tmp;
console.writeline (“written count={0}”, tmp);
}
thread.sleep(30);
}
thread.join();
console.writeline (“final count: {0}”, count);
}
static void threadjob()
{
for (int i=0; i < 5; i++)
{
lock (countlock)
{
int tmp = count;
console.writeline (“\t\t\t\tread count={0}”, tmp);
thread.sleep(20);
tmp++;
console.writeline (“\t\t\t\tincremented tmp to {0}”, tmp);
if (count < 100)
throw new exception();
thread.sleep(10);
count = tmp;
console.writeline (“\t\t\t\twritten count={0}”, tmp);
}
thread.sleep(40);
}
}
}
结果如何?与monitorthread.cs比较一下,再想想看。
