在.NET中多线程的锁机制

在系统上运行的程序都是一个进程,一个进程又包含一个或多个线程。我们可以把进程理解为一个应用程序,而线程就时这个应用程序的特殊代码段,它可以在应用程序中独立的运行。所以可以认为线程是轻量级的进程,通常情况下,操作系统会负责多个线程的调度和执行。

而多线程是为了在同一个段时间内,完成多个工作,通常又被称为异步操作,以此来提高系统的效率。

使用线程的优点有以下几点:

1.         使用线程可以把占据时间长的程序中的任务放到后台去处理

2.         用户界面可以更加吸引人,这样比如用户点了一个按钮去触发某些事件的处理,我们可以弹出一个进度条,来显示处理的进度

3.         由于可以异步操作,程序的运行速度会加快。

4.         在一些需要等待的任务实现上,如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些宝贵的资源如内存占用等。

下面进入正题,说一说.NET的多线程。.NET时一个多线程的环境。有两种主要的多线程方法是.NET所提倡的:一是使用ThreadStart来开始你自己的进程,二是直接使用ThreadPool.QueueUserWorkItem或间接使用ThreadPool这个类,比如Stream.BeginRead, BeginInvoke.。一般来说,你可以手动为需要长时间运行的任务创建一个新的线程,另外对于短时间运行的任务尤其是经常需要开始的那些任务,进程池是一个非常好的选择。进程池可以同时运行多个任务,而且对于资源紧缺需要同步进行的情况来说,它可以限制某一时刻只允许一个线程访问资源。这种情况下可以视为给线程实现了锁机制。

关于锁机制,我的理解是,对于某个资源,或是某段代码,只允许同步访问,不运行异步访问,就是说当一个线程在使用时,其他的线程就不能再访问,要访问必须要等到当前的线程使用结束,或者是离开这段代码。我用下面的代码来说明这个问题,供大家参考交流。

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,object state)

    {

        // 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)

        {

            Console.WriteLine("/n"+state .ToString ()+ " Start Withdraw:");

            Thread.Sleep(1000);

            if (balance >= amount)

            {

                Console.WriteLine("Balance before Withdrawal : " + balance);

                Console.WriteLine("Amount to Withdraw : -" + amount);

                balance = balance - amount;

                Console.WriteLine("Balance after Withdrawal : " + balance);

               

                Console.WriteLine(state.ToString() + "  End Withdraw:/n");

                return amount;

            }

            else

            {

                Console.WriteLine(state.ToString() + "  End Withdraw:/n");

                return 0; // transaction rejected

            }

 

        }

    }

    public void DoTransactions(object state)

    {

        for (int i = 0; i < 20; i++)

        {

            Withdraw(r.Next(1, 20),state );

        }

    }

}

class Test

{

    static void Main()

  {

    Account acc = new Account(20);

      ThreadPool.QueueUserWorkItem(new WaitCallback(acc.DoTransactions), "one");

      ThreadPool.QueueUserWorkItem(new WaitCallback(acc.DoTransactions), "two");

      Console.ReadKey();

  }

}

图11

图22

 

 

 

 

 

 

1,是加锁的情况,从截图中可以看出,两个线程对加锁段代码的访问是同步的,一个一个的访问,

2,是没有加锁的情况,从截图中可以看出,线程one,还没有结束,线程two,就开始访问代码段了。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值