描述C#多线程中lock关键字的使用分析

本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。
每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数。这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生。
C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待。在C# lock关键字定义如下:
lock(expression) statement_block
expression代表你希望跟踪的对象,通常是对象引用。
如果你想保护一个类的实例,一般地,你可以使用this;如果你想保护一个静态变量(如互斥代码段在一个静态方法内部),一般使用类名就可以了。
而statement_block就是互斥段的代码,这段代码在一个时刻内只可能被一个线程执行。
下面是一个使用C# lock关键字的典型例子,在注释里说明了C# lock关键字的用法和用途。
示例如下:


代码如下:

using System;
using System.Threading;
namespace ThreadSimple
{
    internal class Account
    {
        int balance; //余额
        Random r=new Random();
        internal Account(int initial) 
        { 
            balance=initial;
        }
        internal int Withdraw(int amount) //取回、取款
        {
            if(balance<0)
            { 
                //如果balance小于0则抛出异常 
                throw new Exception("NegativeBalance");//负的 余额
            }
            //下面的代码保证在当前线程修改balance的值完成之前
            //不会有其他线程也执行这段代码来修改balance的值 
            //因此,balance的值是不可能小于0的 
            lock(this) 
            {
                Console.WriteLine("CurrentThread:"+Thread.CurrentThread.Name);
                //如果没有lock关键字的保护,那么可能在执行完if的条件判断(成立)之后 
                //另外一个线程却执行了balance=balance-amount修改了balance的值
                //而这个修改对这个线程是不可见的,所以可能导致这时if的条件已经不成立了
                //但是,这个线程却继续执行 balance=balance-amount,所以导致balance可能小于0
                if(balance>=amount)
                {
                    Thread.Sleep(5);
                    balance=balance-amount;
                    return  amount;
                }  else
                {
                    return 0;
                    //transactionrejected
                }
            } 
        }
        internal void DoTransactions()//取款事务
        {
            for (int i = 0; i < 100; i++)
            {
                Withdraw(r.Next(-50, 100));
            }
        }
    }  
    internal class Test 
    { 
        static internal Thread[] threads=new Thread[10];
        public static void Main() 
        { 
            Account acc=new Account(0);
            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].Name = i.ToString();
            }
            for (int i = 0; i < 10; i++)
            {
                threads[i].Start();
                Console.ReadLine();
            }
        }
    }
}

(0)

相关推荐

  • C#中lock用法详解

    本文实例讲述了C#中lock的用法.分享给大家供大家参考.具体分析如下: lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断.这是通过在代码块运行期间为给定对象获取互斥锁来实现的. 先来看看执行过程,代码示例如下: lock 语句用于获取某个给定对象的互斥锁,执行一个语句,然后释放该锁. lock-statement:(lock 语句:) 复制代码 代码如下: lock(expression) embedded-statement(lock   (   表达式   )   嵌入语句

  • C#中Monitor对象与Lock关键字的区别分析

    Monitor对象 1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取锁之后因为异常,致锁无法释放,所以需要在try{} catch(){}之后的finally{}结构体中释放锁(Monitor.Exit()).2.Monitor的常用属性和方法: Enter(Object) 在指定对象上获取排他锁. Exit(Object) 释放指定对象上的排他锁. IsEnter

  • 如何使用C#读写锁ReaderWriterLockSlim

    读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能. 某些场合下,对一个对象的读取次数远远大于修改次数,如果只是简单的用lock方式加锁,则会影响读取的效率.而如果采用读写锁,则多个线程可以同时读取该对象,只有等到对象被写入锁占用的时候,才会阻塞. 简单的说,当某个线程进入读取模式时,此时其他线程依然能进入读取模式,假设此时一个线程要进入写入模式,那么他不得不被阻塞

  • 解析使用C# lock同时访问共享数据

    经常碰到同时需要对某个数据进行操作,或者对某个文件进行读写操作,对于这些操作我们以前往往不能很好的进行处理,自从C#语言中引入了lock这个关键字,以上问题就比较容易予以解决了,下面就是一段简单的代码. 复制代码 代码如下: public class AccessControl(){    private static object privateObjectLock = new object();    public static AccessResult()    {       lock(

  • C#中的lock、Monitor、Mutex学习笔记

    线程:线程是进程的独立执行单元,每一个进程都有一个主线程,除了主线程可以包含其他的线程. 多线程的意义:多线程有助于改善程序的总体响应性,提高CPU的效率. 多线程的应用程序域是相当不稳定的,因为多个线程在同一时间内都能运行共享的功能模块.为了保护应用程序的资源不被破坏,为多线程程序提供了三种加锁的机制,分别是:Monitor类.Lock关键字和Mutex类. 1. lock lock实现的功能是:使后进入的线程不会中断当前的线程,而是等待当前线程结束后再继续执行. 应用: 复制代码 代码如下:

  • C#中实现线程同步lock关键字的用法详解

    1. lock关键字保证一个代码块在执行的过程中不会受到其他线程的干扰,这是通过在该代码块的运行过程中对特定的对象加互斥锁来实现的. 2. lock关键字的参数必须是引用类型的对象.lock对基本数据类型如int,long等无效,因为它所作用的类型必须是对象.如果传入long类型数据,势必被转换为Int64结构类型,则加锁的是全新的对象引用.如果需要对它们进行互斥访问限制,可以使用System.Threading.Interlocked类提供的方法,这个类是提供原子操作的. 3. lock(th

  • C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法

    本文实例讲述了C#多线程编程之使用ReaderWriterLock类实现多用户读与单用户写同步的方法.分享给大家供大家参考,具体如下: 摘要:C#提供了System.Threading.ReaderWriterLock类以适应多用户读/单用户写的场景.该类可实现以下功能:如果资源未被写操作锁定,那么任何线程都可对该资源进行读操作锁定,并且对读操作锁数量没有限制,即多个线程可同时对该资源进行读操作锁定,以读取数据. 使用Monitor或Mutex进行同步控制的问题:由于独占访问模型不允许任何形式的

  • C#中lock死锁实例教程

    在c#中有个关键字lock,它的作用是锁定某一代码块,让同一时间只有一个线程访问该代码块,本文就来谈谈lock关键字的原理和其中应注意的几个问题: lock的使用原型是: lock(X) { //需要锁定的代码.... } 首先要明白为什么上面这段话能够锁定代码,其中的奥妙就是X这个对象,事实上X是任意一种引用类型,它在这儿起的作用就是任何线程执行到lock(X)时候,X需要独享才能运行下面的代码,若假定现在有3个线程A,B,C都执行到了lock(X)而ABC因为此时都占有X,这时ABC就要停下

  • c#多线程中Lock()关键字的用法小结

    本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待. 每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数.这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生. 其中,lock是一种比较好用的简单的线程同步方式,它是通过为给定对象获取互斥锁来实现同步的.它可以保证当一个线程在关键

  • 描述C#多线程中lock关键字的使用分析

    本文介绍C# lock关键字,C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一个线程进入执行,而其他线程必须等待.每个线程都有自己的资源,但是代码区是共享的,即每个线程都可以执行相同的函数.这可能带来的问题就是几个线程同时执行一个函数,导致数据的混乱,产生不可预料的结果,因此我们必须避免这种情况的发生.C#提供了一个关键字lock,它可以把一段代码定义为互斥段(critical section),互斥段在一个时刻内只允许一

  • Java多线程中Lock锁的使用总结

    多核时代 摩尔定律告诉我们:当价格不变时,集成电路上可容纳的晶体管数目,约每隔18个月便会增加一倍,性能也将提升一倍.换言之,每一美元所能买到的电脑性能,将每隔18个月翻两倍以上.然而最近摩尔定律似乎遇到了麻烦,目前微处理器的集成度似乎到了极限,在目前的制造工艺和体系架构下很难再提高单个处理器的速度了,否则它就被烧坏了.所以现在的芯片制造商改变了策略,转而在一个电路板上集成更多的处理器,也就是我们现在常见的多核处理器. 这就给软件行业带来麻烦(也可以说带来机会,比如说就业机会,呵呵).原来的情况

  • Java多线程中Lock锁的使用小结

    Lock基本使用 Lock它是java.util.concurrent.locks下的一个接口,它也是用来处理线程同步问题的. public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void

  • 对python多线程中Lock()与RLock()锁详解

    资源总是有限的,程序运行如果对同一个对象进行操作,则有可能造成资源的争用,甚至导致死锁 也可能导致读写混乱 锁提供如下方法: 1.Lock.acquire([blocking]) 2.Lock.release() 3.threading.Lock() 加载线程的锁对象,是一个基本的锁对象,一次只能一个锁定,其余锁请求,需等待锁释放后才能获取 4.threading.RLock() 多重锁,在同一线程中可用被多次acquire.如果使用RLock,那么acquire和release必须成对出现,

  • Python中super关键字用法实例分析

    本文实例讲述了Python中super关键字用法.分享给大家供大家参考.具体分析如下: 在Python类的方法(method)中,要调用父类的某个方法,在Python 2.2以前,通常的写法如代码段1: 代码段1: class A: def __init__(self): print "enter A" print "leave A" class B(A): def __init__(self): print "enter B" A.__init

  • JavaScript中this关键字用法实例分析

    本文实例总结了JavaScript中this关键字用法.分享给大家供大家参考,具体如下: 例1: function a(){ var user = "yao"; console.log(this.user);//undefined console.log(this);//window } a(); 等价于: function a(){ var user = "yao"; console.log(this.user);//undefined console.log(t

  • python中的多线程锁lock=threading.Lock()使用方式

    目录 多线程锁lock=threading.Lock()使用 疑问 解决方法 例子 python多线程中锁的概念 锁可以独立提取出来 概念 线程不安全 线程锁 多线程锁lock=threading.Lock()使用 疑问 多线程任务是同时执行的,如果我们需要先执行线程a,再执行线程b,需要怎么办呢? 解决方法 使用python的多线程锁lock. 例子 未使用多线程锁lock: def a():     for i in range(3):         print('a%d' % (i +

随机推荐