AsnycLocal与ThreadLocal

AsnyncLocal与ThreadLocal都是存储线程上下文的变量,但是,在实际使用过程中两者又有区别主要的表现在:

  • AsyncLocal变量可以在父子线程中传递,创建子线程时父线程会将自己的AsyncLocal类型的上下文变量赋值到子线程中,但是,当子线程改变线程上下文中AsnycLocal变量值后,父线程不会同步改变。也就是说AsnycLocal变量只会影响他的子线程,不会影响他的父级线程。
  • TreadLocal只是当前线程的上下文变量,不能在父子线程间同步。
using System;
using System.Threading;
using System.Threading.Tasks; namespace await_aysnc
{
class Program
{
static ThreadLocal<int> ThreadObj = new ThreadLocal<int>();
static AsyncLocal<int> AsyncObj = new AsyncLocal<int>(); static void Main(string[] args)
{
AsyncObj.Value = 1;
ThreadObj.Value = 1;
Console.WriteLine($"Task执行前:AsyncObj= {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}");
Task.Run(async() =>
{
Console.WriteLine($"RunAsync异步执行前:AsyncObj= {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}");
await RunAsync();
Console.WriteLine($"RunAsync异步执行后:AsyncObj = {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}");
});
Console.WriteLine($"Task执行后:AsyncObj= {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}");
Console.Read();
} static async Task RunAsync()
{
Console.WriteLine($"Delay异步执行前:AsyncObj = {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId} ");
AsyncObj.Value = 2;
ThreadObj.Value = 2;
await Task.Delay(100);
Console.WriteLine($"Delay异步执行后:AsyncObj = {AsyncObj.Value} ThreadObj= {ThreadObj.Value} ThreeadId = {Thread.CurrentThread.ManagedThreadId}");
}
} }
Task执行前:AsyncObj= 1 ThreadObj= 1 ThreeadId = 1
Task执行后:AsyncObj= 1 ThreadObj= 1 ThreeadId = 1
RunAsync异步执行前:AsyncObj= 1 ThreadObj= 0 ThreeadId = 3
Delay异步执行前:AsyncObj = 1 ThreadObj= 0 ThreeadId = 3
Delay异步执行后:AsyncObj = 2 ThreadObj= 0 ThreeadId = 4
RunAsync异步执行后:AsyncObj = 1 ThreadObj= 0 ThreeadId = 4

从结果上可以看出一下结论:

  • RunAsync执行前ThreadLocal值被切成0即ThreadLocal变量在新线程里面没有继承主线程的上下文变量,但是AsyncLocal继承了。
  • Delay返回后,线程id变了,同时,TheadLocal中的变量为0。
  • RunAsync结束后AyncLocal又切回主线程的上下文值,,同样Threadlocal中的值丢失。
  • 由于await执行完返回之后,.net会在线程池中随机选取一个线程来执行await之后的逻辑,所以,await之后同时也会有一定几率获取到之前的线程,如果出现这种情形,TreadLocal会获取到之前的上下文,此时会出现意料之外的问题,从现象上看报错可能会是一个概率性问题。

AsnycLocal与ThreadLocal的更多相关文章

  1. c#中多线程间的同步

    目录 一.引入 二.Lock 三.Monitor 四.Interlocked 五.Semaphore 六.Event 七.Barrier 八.ReaderWriterLockSlim 九.Mutex ...

  2. ThreadLocal简单理解

    在java开源项目的代码中看到一个类里ThreadLocal的属性: private static ThreadLocal<Boolean> clientMode = new Thread ...

  3. Android线程管理之ThreadLocal理解及应用场景

    前言: 最近在学习总结Android的动画效果,当学到Android属性动画的时候大致看了下源代码,里面的AnimationHandler存取使用了ThreadLocal,激起了我很大的好奇心以及兴趣 ...

  4. Threadlocal使用Case

    Threadlocal能够为每个线程分配一份单独的副本,使的线程与线程之间能够独立的访问各自副本.Threadlocal 内部维护一个Map,key为线程的名字,value为对应操作的副本. /** ...

  5. 多线程映射工具——ThreadLocal

    ThreadLocal相当于一个Map<Thread, T>,各线程使用自己的线程对象Thread.currentThread()作为键存取数据,但ThreadLocal实际上是一个包装了 ...

  6. ThreadLocal 工作原理、部分源码分析

    1.大概去哪里看 ThreadLocal 其根本实现方法,是在Thread里面,有一个ThreadLocal.ThreadLocalMap属性 ThreadLocal.ThreadLocalMap t ...

  7. ThreadLocal<T>的是否有设计问题

    一.吐槽 ThreadLocal<T>明显是.NET从JAVA中来的一个概念,但是这种设计是否出现了问题. 很明显,在JAVA中threadLocal直接是Thread的成员,当然随着th ...

  8. 理解ThreadLocal —— 一个map的key

    作用: 当工作于多线程中的对象使用ThreadLocal维护变量时,threadLocal为每个使用该变量的线程分配一个独立的变量副本. 接口方法: protected T initialValue( ...

  9. JavaSe:ThreadLocal

    JDK中有一个ThreadLocal类,使用很方便,但是却很容易出现问题.究其原因, 就是对ThreadLocal理解不到位.最近项目中,出现了内存泄漏的问题.其中就有同事在使用ThreadLocal ...

随机推荐

  1. svn重新安装后报You need to upgrade the working copy first错误

    问题来源 最近重新安装了操作系统,安装了一个最新版的svn,提交代码的时候报了一个错误:You need to upgrade the working copy first,!网上找了很多解决办法,都 ...

  2. Python小白学习之路(二十三)—【生成器补充】

    生成器的一些补充 接着下鸡蛋和吃包子! 补充一:生成器只能遍历一次 (总是把生成器比喻成母鸡下鸡蛋,需要一个下一个,首先是下出来的鸡蛋不能塞回母鸡肚子里,其次是一个母鸡一生只能下一定数量的鸡蛋,下完了 ...

  3. 08-03 java 继承

    继承格式,优缺点,概述: /* 继承概述: 把多个类中相同的内容给提取出来定义到一个类中. 如何实现继承呢? Java提供了关键字:extends 格式: class 子类名 extends 父类名 ...

  4. Python相关在线文档手册地址

    Python相关: 五星推荐:http://python.usyiyi.cn/ Python 2.7官方中文文档:http://doc.iplaypy.com/python2/  英文:    htt ...

  5. 安装Centos7 随手记

    1.老笔记本安装Centos7 配置:酷睿I3  内存8G 2.原有系统Win7 将原来的硬盘空间,调整出60G 给Centos7 用. 3.安装Centos7 图形介面的,和windows安装过程类 ...

  6. Shell 流程控制 if while for

    if else if if 语句语法格式: if condition then command1 command2 ... commandN fi 写成一行(适用于终端命令提示符): if [ $(p ...

  7. Android学习总结——INSTALL_FAILED_CONFLICTING_PROVIDER

    在写个小demo的时候出现了这个问题: 排除手机内存不足.以及没用安装过这个应用的问题之后,发现是android:authorities="..."出了问题,可能还有其他应用程序和 ...

  8. jquery控制input只能输入数字和两位小数

    jquery代码 function num(obj){ obj.value = obj.value.replace(/[^\d.]/g,""); //清除"数字" ...

  9. redis乐观锁(适用于秒杀系统)

    redis事务中的WATCH命令和基于CAS的乐观锁  在Redis的事务中,WATCH命令可用于提供CAS(check-and-set)功能.假设我们通过WATCH命令在事务执行之前监控了多个Key ...

  10. 【一个小功能】点击图标/链接发起QQ临时会话

    有时候,我们需要实现在网页上点击一个QQ图标来实现QQ临时会话,这样不用添加好友,也能满足及时沟通的需求. 实现方案比较简单,只是为a标签修改href属性,代码如下 <a href=" ...