C# Lock关键字

原创 2017年10月13日 10:40:58

 

lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。

 

lock语句根本使用的就是Monitor.Enter和Monitor.Exit,也就是说lock(this)时执行Monitor.Enter(this),大括号结束时执行Monitor.Exit(this).他的意义在于什么呢,对于任何一个对象来说,他在内存中的第一部分放置的是所有方法的地址,第二部分放着一个索引,他指向CLR中的SyncBlock Cache区域中的一个SyncBlock.什么意思呢?就是说,当你执行Monitor.Enter(Object)时,如果object的索引值为负数,就从SyncBlock Cache中选区一个SyncBlock,将其地址放在object的索引中。这样就完成了以object为标志的锁定,其他的线程想再次进行Monitor.Enter(object)操作,将获得object为正数的索引,然后就等待。直到索引变为负数,即线程使用Monitor.Exit(object)将索引变为负数。


使用lock需要注意的地方:

1.lock不能锁定空值某一对象可以指向Null,但Null是不需要被释放的。(请参考:认识全面的null)
2.lock不能锁定string类型,虽然它也是引用类型的。因为字符串类型被CLR“暂留”

这意味着整个程序中任何给定字符串都只有一个实例,就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本。因此,只要在应用程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例。因此,最好锁定不会被暂留的私有或受保护成员。
3.lock锁定的对象是一个程序块的内存边界
4.值类型不能被lock,因为前文标红字的“对象被释放”,值类型不是引用类型的

5.lock就避免锁定public 类型或不受程序控制的对象。
例如,如果该实例可以被公开访问,则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。这可能导致死锁,即两个或更多个线程等待释放同一对象。出于同样的原因,锁定公共数据类型(相比于对象)也可能导致问题。
使用lock(this)的时候,类的成员变量的值可能会被不在临界区的方法改值了

 

应用场景:经常会应用于防止多线程操作导致公用变量值出现不确定的异常,用于确保操作的安全性

 

示例


// statements_lock2.cs
using System;
using System.Threading;

class Account
{
    private Object thisLock = new Object();
    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(thisLock)
        {
            if (balance >= amount)
            {
                Console.WriteLine("Balance before Withdrawal :  " + balance);
                Console.WriteLine("Amount to Withdraw        : -" + amount);
                balance = balance - amount;
                Console.WriteLine("Balance after Withdrawal  :  " + balance);
                return amount;
            }
            else
            {
                return 0; // transaction rejected
            }
        }
    }

    public void DoTransactions()
    {
        for (int i = 0; i < 100; i++)
        {
            Withdraw(r.Next(1, 100));
        }
    }
}

class Test
{
    static void Main()
    {
        Thread[] threads = new Thread[10];
        Account acc = new Account(1000);
        for (int i = 0; i < 10; i++)
        {
            Thread t = new Thread(new ThreadStart(acc.DoTransactions));
            threads[i] = t;
        }
        for (int i = 0; i < 10; i++)
        {
            threads[i].Start();
        }
    }
}

 

 

以上图片由“图斗罗”提供

C#Lock关键字的使用

前言       这shu'yu
  • xiaojia7283
  • xiaojia7283
  • 2014年08月22日 15:10
  • 582

C#中的lock关键字

在实现Unity中的单例模式时看到的,讲解Lock的用法,作者写的明白,转过来自己收藏一下。 原文连接 : http://kb.cnblogs.com/page/88513/        ...
  • Haohan_Meng
  • Haohan_Meng
  • 2014年01月22日 11:59
  • 4864

C# lock用法实例

源地址:http://hi.baidu.com/jiang_yy_jiang/item/55cc8a105414d38988a956a4
  • ful1021
  • ful1021
  • 2014年04月22日 09:26
  • 524

C#之lock关键字 lock锁定语句

lock 关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。下面的示例包含一个 lock 语句。 class Account ...
  • makenothing
  • makenothing
  • 2014年04月24日 10:06
  • 1475

volatile,lock,synchronized

volatile 关键字表示字段可能被多个并发执行线程修改。声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈现的都是最新的值。 vola...
  • kingmax54212008
  • kingmax54212008
  • 2015年11月09日 07:41
  • 788

lock关键字的用法。弄懂了。

原址:http://www.csharpwin.com/csharpspace/12362r6119.shtml 一直以来对于lock关键字的用法都存有疑惑,也从网上看到很多...
  • ldghd
  • ldghd
  • 2014年01月16日 14:08
  • 757

C# Lock 关键字锁定静态变量和非静态变量的区别

private static readonly object Locker1 = new object(); private readonly object Locker2 = new object(...
  • huijunma2010
  • huijunma2010
  • 2016年12月09日 16:47
  • 983

C# volatile ,lock解析

http://mxmkeep.blog.163.com/blog/static/10649241520096410448715/ (C# 参考)volatile,lock,synchronized C...
  • pretyjfh
  • pretyjfh
  • 2010年08月08日 10:44
  • 6113

Java 多线程:Lock 关键字

sleep() & interrupt()线程A正在使用sleep()暂停着: Thread.sleep(100000); 如果要取消他的等待状态,可以在正在执行的线程里(比如这里是B)调用 a.in...
  • Allen215902
  • Allen215902
  • 2016年03月14日 21:53
  • 513

C# lock关键字

lock关键字可以把一段代码定义为互斥段。互斥段的作用:是在同一时刻只有一个线程可以进入执行此段代码。 每个线程都有自己的资源,但代码段都是共享的。即每个线程都可以执行相同的函数。这可能带来的问题就是...
  • wrq147
  • wrq147
  • 2010年01月02日 11:31
  • 1674
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# Lock关键字
举报原因:
原因补充:

(最多只允许输入30个字)