异步线程学习笔记(四) 线程安全

在学习线程安全之前,我们需要了解两个概念,什么叫做本地和共享。
1)本地独立:
CLR会为每个线程分配自己的内存栈,以便使本地变量保持独立。
2)共享:
如果多个线程引用了同一个对象的实例,那么它们就共享了数据。

class ThreadTest
    {
        bool _done;
        static void Main()
        {
            ThreadTest tt = new ThreadTest();//创建了一个共同的实例
            new Thread(tt.Go).Start();
            tt.Go();
        }
        void Go()//实例方法
      {
            if (!_done)
            {
                _done = true;
                Console.WriteLine("Done");
            }
        }
    }



在上例中,我们可以看到主线程使用了ThreadTest的同一个实例,这里的_done变量是共享的。

此外,被Lambda表达式或者匿名委托所捕获的本地变量,会被编译器转换成字段,也会被共享,静态字段也会在线程间共享。

class ThreadTest
    {
        static void Main()
        {
            bool done = false;
            ThreadStart action = () =>
              {
                  if (!done)
                  {
                      done = true;
                      Console.WriteLine("Done");
                  }
              };
            new Thread(action).Start();
            action();
        }
    }
















这里的done变量是共享的。

在了解了本地和共享状态后,我们可以引出一个新的概念即线程安全。
在第一个案例debug之后,我们可以打印出一个Done,但是假如主线程和新线程在_done变量未变成true之前都进入到if语句了呢?那么,我们会得到两个Done。这样的线程很明显是不安全的。
所以,线程安全指的就是:在多线程的上下文转换中,可以避免不确定性的代码就可以称作线程安全。

如何实现线程安全:
在读取和写入共享数据的时候,通过Lock保证,两个线程同时竞争同一个锁的时候,一个线程会等待或者阻塞,知道这个锁变成可用状态。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值