看一下以下两个例子的运行结果:
//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比较一下,再想想看。