ThreadLocal

在多线程环境下,每个线程都有自己的数据。一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁。

1. 使用函数传参的方法

但是局部变量也有问题,就是在函数调用的时候,传递起来很麻烦:

def process_student(name):
std = Student(name)
# std是局部变量,但是每个函数都要用它,因此必须传进去:
do_task_1(std)
do_task_2(std) def do_task_1(std):
do_subtask_1(std)
do_subtask_2(std) def do_task_2(std):
do_subtask_2(std)
do_subtask_2(std)

每个函数一层一层调用都这么传参数那还得了?用全局变量?也不行,因为每个线程处理不同的Student对象,不能共享

2. 使用全局字典的方法

如果用一个全局dict存放所有的Student对象,然后以thread自身作为key获得线程对应的Student对象如何?

global_dict = {}

def std_thread(name):
std = Student(name)
# 把std放到全局变量global_dict中:
global_dict[threading.current_thread()] = std
do_task_1()
do_task_2() def do_task_1():
# 不传入std,而是根据当前线程查找:
std = global_dict[threading.current_thread()]
... def do_task_2():
# 任何函数都可以查找出当前线程的std变量:
std = global_dict[threading.current_thread()]
...

这种方式理论上是可行的,它最大的优点是消除了std对象在每层函数中的传递问题,但是,每个函数获取std的代码有点low。

有没有更简单的方式?

    

3. 使用ThreadLocal的方法

ThreadLocal应运而生,不用查找dict,ThreadLocal帮你自动做这件事:

import threading

# 创建全局ThreadLocal对象:
local_school = threading.local() def process_student():
# 获取当前线程关联的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name)) def process_thread(name):
# 绑定ThreadLocal的student:
local_school.student = name
process_student() t1 = threading.Thread(target= process_thread, args=('dongGe',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('老王',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()

      

      

说明

全局变量local_school就是一个ThreadLocal对象,每个Thread对它都可以读写student属性,但互不影响。你可以把local_school看成全局变量,但每个属性如local_school.student都是线程的局部变量,可以任意读写而互不干扰,也不用管理锁的问题,ThreadLocal内部会处理。

可以理解为全局变量local_school是一个dict,不但可以用local_school.student,还可以绑定其他变量,如local_school.teacher等等。

ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源。

4. 小结

一个ThreadLocal变量虽然是全局变量,但每个线程都只能读写自己线程的独立副本,互不干扰。ThreadLocal解决了参数在一个线程中各个函数之间互相传递的问题

13 ThreadLocal的更多相关文章

  1. ThreadLocal模式的原理

    在JDK的早期版本中,提供了一种解决多线程并发问题的方案:java.lang.ThreadLocal类.ThreadLocal类在维护变量时,实际使用了当前线程(Thread)中的一个叫做Thread ...

  2. 面试挂了阿里却拿到网易offer,一个三年Java程序员的面试总结!

    前言 15年毕业到现在有三年多了,最近去面试了阿里集团(菜鸟网络,蚂蚁金服),网易,滴滴,点我达,最终收到点我达,网易offer,蚂蚁金服二面挂掉,菜鸟网络一个月了还在流程中... 最终有幸去了网易. ...

  3. java并发编程实践——王宝令(极客时间)学习笔记

    1.并发 分工:如何高效地拆解任务并分配给线程 同步:线程之间如何协作 互斥:保证同一时刻只允许一个线程访问共享资源 Fork/Join 框架就是一种分工模式,CountDownLatch 就是一种典 ...

  4. 工作三年终于社招进字节跳动!字节跳动,阿里,腾讯Java岗面试经验汇总

    前言 我大概我是从去年12月份开始看书学习,到今年的6月份,一直学到看大家的面经基本上百分之90以上都会,我就在5月份开始投简历,边面试边补充基础知识等.也是有些辛苦.终于是在前不久拿到了字节跳动的o ...

  5. 备战-Java 并发

    备战-Java 并发 谁念西风独自凉,萧萧黄叶闭疏窗 简介:备战-Java 并发. 一.线程的使用 有三种使用线程的方法: 实现 Runnable 接口: 实现 Callable 接口: 继承 Thr ...

  6. 面渣逆袭:Java并发六十问,快来看看你会多少道!

    大家好,我是老三,面渣逆袭 继续,这节我们来盘一盘另一个面试必问知识点--Java并发. 这篇文章有点长,四万字,图文详解六十道Java并发面试题.人已经肝麻了,大家可以点赞.收藏慢慢看!扶我起来,我 ...

  7. 【转】Java并发编程:深入剖析ThreadLocal

    来自: http://www.importnew.com/17849.html 想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理.首先,本 ...

  8. 理解ThreadLocal(之二)

    想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理.首先,本文先谈一下对ThreadLocal的理解,然后根据ThreadLocal类的源码 ...

  9. ThreadLocal()理解

    在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地编写出优美的多线程程序. 当使用 ...

随机推荐

  1. 第一次团队Scrum

                                    长大一条龙之成绩查询 一.项目介绍             本项目的意义在于锻炼团队的scrum能力,加强团队合作能力.确定本项目采用的 ...

  2. Android(java)学习笔记26:File类的使用

    1. File类的使用  package cn.itcast_01; import java.io.File; /* * 我们要想实现IO的操作,就必须知道硬盘上文件的表现形式. * 而Java就提供 ...

  3. POJ 最小球覆盖 模拟退火

    最小球覆盖:用半径最小的球去覆盖所有点. 纯粹的退火算法,是搞不定的,精度不够,不然就会TLE,根本跑不出答案来. 任取一点为球心,然后一点点靠近最远点.其实这才是最主要的. 因为:4个点确定一个球, ...

  4. luogu4566 [Vani有约会]雨天的尾巴

    题目 线段树合并的板子题目了,写一写对线段树合并的理解 首先线段树合并就是把一大堆权值线段树合并起来的算法 尽管复杂度看起来并不是非常科学,但是确是非常优秀的\(O(nlogn)\) 主要的写法两种 ...

  5. Ubuntu连接上海大学校园网(ShuWlan-1x & Shu(For All))

    1.连接Shu(For All):直接连接,打开网页后可能会自动弹出登录页面,也可能需要点击浏览器菜单栏下方的跳转按钮. 2.连接ShuWlan-1x配置注意点: 认证方式:Protected EAP ...

  6. 【luogu P2299 Mzc和体委的争夺战】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2299#sub 裸的迪杰斯特拉(我是在考试前复习一下板子) #include<iostream> ...

  7. Linux 和类 Unix 系统上5个最佳开源备份工具

    转载:http://linux.cn/article-4623-weixin.html#rd?sukey=cbbc36a2500a2e6cb7678c4d38b691a9fa7403b259f898e ...

  8. mysql自连接

    自连接: -- 求7369员工编号,姓名,经理编号和经理姓名 select e1.empno,e1.ename,e2.empno,e2.ename from emp e1,emp e2 where e ...

  9. MVC5 Attribute(特性)

    AuthorizeAttribute:一般用来判断权限 ActionFilterAttribute:方法执行前后动作 OutputCacheAttribute:输出缓存设置 注:我们创建名称的时候请带 ...

  10. [HP-UNIX]bdf命令总结

    (1)bdf命令的效果 lijiaman$[/home/oracle]bdf Filesystem kbytes used avail %used Mounted on /dev/vg00/lvol3 ...