内容参考自:http://daimajishu.iteye.com/blog/1079107

一. 基本使用形式

二.应用举例

三.需要注意的地方

四.lock应避免锁定public 类型或不受程序控制的对象,举例

五.原理说明

 

lock就是把一段代码定义为临界区,所谓临界区就是同一时刻只能有一个线程来操作临界区的代码,当一个线程位于代码的临界区时,另一个线程不能进入临界区,如果试图进入临界区,则只能一直等待(即被阻止),直到已经进入临界区的线程访问完毕,并释放锁旗标。

其基本使用方式如下:

class Test
{
    //定义一个私有成员变量,用于Lock的锁定标志  
    private static object lockobj = new object();
    void DoSomething()
    {
        lock (lockobj)
        {
            //需要锁定的代码块  
        }
    }
}  

最经典的例子,莫过于模拟银行5个窗口取钱操作的例子了,5个窗口是5个线程,都要取钱,但是同一刻只能有一个窗口可以进行真正的取钱操作(钱数的数值计算,剩余多少等这些代码必须定义为临界区),其他只有等待,其代码如下:

class Account
{
    int balance;
    Random r = new Random();
    public Account(int initial)
    {
        balance = initial;
    }

    int Withdraw(int amount)
    {

        // This condition will never be true unless the lock statement  
        // is commented out:  
        if (balance < 0)
            throw new Exception("Negative Balance");

        // Comment out the next line to see the effect of leaving out   
        // the lock keyword:  
        lock (this)
        {
            if (balance >= amount)
            {
                Console.WriteLine("提款窗口:  " + Thread.CurrentThread.Name);
                Console.WriteLine("提款之前余额(Balance before Withdrawal):  " + balance);
                Console.WriteLine("提款数量(Amount to Withdraw)           : -" + amount);
                balance = balance - amount;
                Console.WriteLine("提款之后余额(Balance after Withdrawal) :  " + balance);
                Console.WriteLine();
                return amount;
            }
            else return 0; // transaction rejected  
        }
    }

    public void DoTransactions()
    {
        //模拟100个人来提款,每次提1-30元  
        for (int i = 0; i < 100; i++)
            Withdraw(r.Next(1, 30));
    }
}
class Test
{
    public static void MainXXX()
    {
        Thread[] threads = new Thread[5];

        //总额为100元  
        Account acc = new Account(100);

        //定义并初始化5个线程,模拟银行的5个窗口  
        for (int i = 0; i < 5; i++)
        {
            Thread t = new Thread(new ThreadStart(acc.DoTransactions)) { Name = i + "" };
            threads[i] = t;
        }

        //启动5个线程,模拟银行的5个窗口开始工作  
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("threads[{0}].Start()", i);
            threads[i].Start();
        }
    }
}
View Code

相关文章: