锁定线程
看了几天的线程同步,还是一头雾水,现在只能按照自己的理解写出来,希望大家批评指正! 看下面情况,张三在银行存了1000块钱。某天,张三和他老婆同时想取钱(不知道对方也想取),然后他们来到两个不同的ATM机前(他的卡有一张附属卡),然后两人同时输入取款1000的命令,银行系统先查询账户余额,账户里面有1000块,系统判断金额正确,就执行了......可想而知,银行肯定不会这么干的。为了避免这种情况的发生,银行在取款事件上加了锁,一次只能进入一个,两条命令同时进入的时候,根据一定的规则,进行排队执行。
如果使用多线程操作,我们可以用监视器Monitor或者锁lock进行处理。Monitor提供了Enter,Exit,
TryEnter等方法供我们使用。
using System;
using System.Text;
using System.Threading;
public class Program
{
public static void Main()
{
AAA a = new AAA();
AAA b = new AAA();
Thread ta = new Thread(a.Show);
Thread tb = new Thread(b.Show);
ta.Start();
tb.Start();
Console.Read();
}
}
public class AAA
{
private static object ball = new object();
public object Ball
{
get
{
if (ball == null)
{
ball = new object();
}
return ball;
}
set
{
ball = value;
}
}
public void Show()
{
Monitor.Enter(ball);
Console.WriteLine(Thread.CurrentThread.GetHashCode().ToString());
Thread.Sleep(2000);
Monitor.Exit(ball);
}
}
using System.Text;
using System.Threading;
public class Program
{
public static void Main()
{
AAA a = new AAA();
AAA b = new AAA();
Thread ta = new Thread(a.Show);
Thread tb = new Thread(b.Show);
ta.Start();
tb.Start();
Console.Read();
}
}
public class AAA
{
private static object ball = new object();
public object Ball
{
get
{
if (ball == null)
{
ball = new object();
}
return ball;
}
set
{
ball = value;
}
}
public void Show()
{
Monitor.Enter(ball);
Console.WriteLine(Thread.CurrentThread.GetHashCode().ToString());
Thread.Sleep(2000);
Monitor.Exit(ball);
}
}
通过这个示例可以看到,第二次执行的时候中间等待了2秒,就是不能同时执行了。lock用法和这个差不多。
public void Show()
{
lock (ball)
{
Console.WriteLine(Thread.CurrentThread.GetHashCode().ToString());
Thread.Sleep(2000);
}
}
这里有一个地方要注意,lock函数的参数,我这里定义了私有静态成员作为参数。如果设为this,那就会出问题,只能阻止一个实例的线程,不能阻止其他实例的线程。
{
lock (ball)
{
Console.WriteLine(Thread.CurrentThread.GetHashCode().ToString());
Thread.Sleep(2000);
}
}
using System;
using System.Text;
using System.Threading;
public class Program
{
public static void Main()
{
AAA a = new AAA();
AAA b = new AAA();
a.i = 4;
b.i = 8;
Thread ta = new Thread(a.Show);
Thread tb = new Thread(b.Show);
Thread tc = new Thread(b.Show);
ta.Start();
tb.Start();
tc.Start();
Console.Read();
}
}
public class AAA
{
public int i;
public void Show()
{
lock (this)
{
Console.WriteLine(Thread.CurrentThread.GetHashCode().ToString() + " " + i.ToString());
Thread.Sleep(2000);
}
}
}
这时你会看到类AAA的实例a和实例b的两个线程ta,tb同时执行,只要实例b的两个线程tb和tc被分开执行。所以这样做会有问题,还有用typeof(MyType),字符串作为lock的参数的,都会有问题。这里就不详细介绍了,具体可参看http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/SDaskgui06032003.mspx?mfr=true。
using System.Text;
using System.Threading;
public class Program
{
public static void Main()
{
AAA a = new AAA();
AAA b = new AAA();
a.i = 4;
b.i = 8;
Thread ta = new Thread(a.Show);
Thread tb = new Thread(b.Show);
Thread tc = new Thread(b.Show);
ta.Start();
tb.Start();
tc.Start();
Console.Read();
}
}
public class AAA
{
public int i;
public void Show()
{
lock (this)
{
Console.WriteLine(Thread.CurrentThread.GetHashCode().ToString() + " " + i.ToString());
Thread.Sleep(2000);
}
}
}