今天效率需要,需要搞定一个多线程的程序,今天我用的关键字是Monitor.Enter(this);和Monitor.Exit(this);来说一下到底锁的是什么,之前对java中的同步关键字理解的应该还算可以,锁的时候永远锁的是对象,所以也只有这些线程是在这个对象范围内操作,并且遇到这个关键字才能起到同步的效果。先来一个同步起作用的例子,然后再来一个相反的例子来找个反面典型。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace Threadtest
{
class Program
{
int i = 0;
static void Main(string[] args)
{
Program p = new Program();
for (int j = 0; j < 20; j++)
{
Thread t = new Thread(p.Threadtest);
t.Name = "线程" + (j + 1);
t.Start();
}
Console.Read();
}
private void Threadtest()
{
Monitor.Enter(this);
Console.WriteLine("开始进入");
Thread.Sleep(1000);
Console.WriteLine(Thread.CurrentThread.Name + ":" + i);
Console.WriteLine("退出执行");
i++;
Monitor.Exit(this);
}
}
}
大家可以看到我的多线程都是在一个对象也就是p的上下文中,打印的结果给大家截图一下:
![](http://hi.csdn.net/attachment/201108/28/0_13145311394TSl.gif)
每个线程都是等待另外一个线程出来后才进去的,保持了同步操作。
再来个反面例子:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace Threadtest
{
class Program
{
int i = 0;
static void Main(string[] args)
{
for (int j = 0; j < 20; j++)
{
Program p = new Program();
Thread t = new Thread(p.Threadtest);
t.Name = "线程" + (j + 1);
t.Start();
}
Console.Read();
}
private void Threadtest()
{
Monitor.Enter(this);
Console.WriteLine("开始进入");
Thread.Sleep(1000);
Console.WriteLine(Thread.CurrentThread.Name + ":" + i);
Console.WriteLine("退出执行");
i++;
Monitor.Exit(this);
}
}
}
上截图:
看到没,打印顺序乱了,这是因为我的20个线程每个线程都是不一样的对象p,例子中生成了20个对象p。
最终我想表达的意思就是,线程同步锁的永远是对象(不是类)。。
一般我的做法,如果线程需要运行的代码在另外的代码中的话,我就把另外的类的对象做一个单例,保证线程操作的是一个对象。