.NET 4中的多线程编程之二:共享数据(上)

来源:网络 责任编辑:栏目编辑 发表时间:2013-07-01 23:25 点击:

 

本文侧重实例,关于.NET同步原语的概况介绍,可以参考Overview of Synchronization Primitives .http://msdn.microsoft.com/en-us/library/ms228964.aspx

 

在线程间共享数据有可能会导致竞速状态而发生数据不一致的状态, 例如:

 

namespace TaskParallel

{

    class Account

    {

        public int Balance

        {

            get;

            set;

        }

    }

    class Share

    {

        static void Main(string[] args)

        {

            Account account = new Account { Balance = 0 };

            List<Task> tasks = new List<Task>();

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

            {

                tasks.Add(Task.Factory.StartNew(() =>

                 {

                     for (int j = 0; j < 1000; j++)

                         account.Balance++;    

                 }));

            }

            Task.WaitAll(tasks.ToArray());

            Console.WriteLine(account.Balance);           

        }

    }

}

这段程序中,一共有10个线程,每个线程将一个整型变量自加1000次,期待的结果最终应该是10000,但是运行这段程序的结果每次都不一样而且总比10000小。原因是完成一个变量自加并不是一个原子操作,忽略具体的机器代码不谈,总体上应该是三步,读取当前值,加1,存回计算值.如果线程1读取到了当前值是0,此时被线程2取代而进入等待状态,线程二读取当前值为0,加1,把1存回,线程1接着运行,加1,把1存回。此时Balance的值是1,而已经有线程1和线程2加了2次,数据不一致发生了。下面介绍.Net提供的线程互斥的方法,其实现原理在操作系统原理类的书上有详细介绍,不再赘述。

 

1. 使用Monitor

为了避免不一致发生,必须保证能够改变共享数据的代码在同一时间只有一个线程在执行,要实现这一点,可以使用C#的lock关键字:

object obj = new object();

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

{

     tasks.Add(Task.Factory.StartNew(() =>

     {

           for (int j = 0; j < 1000; j++)

           {

                 lock (obj)

                 {

                      account.Balance++;

        &n

    发表评论
    请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
    用户名: 验证码:点击我更换图片
    最新评论 更多>>

    推荐热点

    • 浅析.NET下XML数据访问新机制
    • asp.net 面试+笔试题目第1/2页
    • C# 邮件地址是否合法的验证
    • asp.net 设置GridView的选中行的实现代码
    • C#高级编程:数据库连接[1]
    • 经典C++程序1
    • IIS 自动回收导致后台定时器失效的问题解决
    • ASP.NET&#160;GridView列表代码示例
    • Asp.net MVC源码分析--Action Filter的链式调用
    网站首页 - 友情链接 - 网站地图 - TAG标签 - RSS订阅 - 内容搜索
    Copyright © 2008-2015 计算机技术学习交流网. 版权所有

    豫ICP备11007008号-1