考试题只有一套,老师把考试题打印出多份,发给每位考生,然后考生各自写各自的试卷。考生之间不能相互交头接耳(会当做作弊)。各自写出来地答案不会影响他人的分数。
注意:考试题、考生、试卷。
用代码来实现:
public?class?ThreadLocalDemo?{????//线程共享变量?localVar????public?static?ThreadLocal<String>?localVar?=?new?ThreadLocal<>();????static?void?print(String?str)?{????????//打印当前线程中本地内存中本地变量的值????????System.out.println(str?+?\"?:\"?+?localVar.get());????????//清除本地内存中的本地变量????????localVar.remove();????}????public?static?void?main(String[]?args)?{????????Thread?t1?=?new?Thread(new?Runnable()?{????????????@Override????????????public?void?run()?{????????????????//设置线程1中本地变量的值????????????????localVar.set(\"全部写完\");????????????????String?threadName?=?Thread.currentThread().getName();????????????????//调用打印方法????????????????print(threadName);????????????}????????},?\"张三\");????????Thread?t2?=?new?Thread(new?Runnable()?{????????????@Override????????????public?void?run()?{????????????????//设置线程2中本地变量的值????????????????localVar.set(\"写了一半\");????????????????String?threadName?=?Thread.currentThread().getName();????????????????//调用打印方法????????????????print(threadName);????????????}????????},?\"李四\");????????Thread?t3?=?new?Thread(new?Runnable()?{????????????@Override????????????public?void?run()?{????????????????//设置线程2中本地变量的值????????????????localVar.set(\"完全没写\");????????????????String?threadName?=?Thread.currentThread().getName();????????????????//调用打印方法????????????????print(threadName);????????????}????????},?\"王二\");????????t1.start();????????t2.start();????????t3.start();????}}输出
李四?:写了一半王二?:完全没写张三?:全部写完ThreadLocal:字面意思为线程本地或者本地线程。但是其实真正含义并非如此,真正的含义是线程本地变量(副本)。
是JDK1.2版本的时候引入的,本文是基于JDK1.8版本进行讲解的。
上面考试场景中的几个关键点我们这么可以这么理解:
考试题----共享变量,大家共享
试卷-----考试题的副本
考试----线程
ThreadLocal可以理解为每个线程想绑定自己的东西,相互不受干扰。比如上面的考试场景,考试题大家都是一样的。但是考试题进行复印出来后,每人一份,各自写写各自的,相互不受影响,这就正是ThreadLocal想要实现的功能。
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
可以想想生活中还有没有类似的例子。肯定非常多,只要我们用心去体会。
下面我们就来看看ThreadLocal到底是如何实现的。
ThreadLocal设计原理ThreadLocal名字中第一个单词Thread表示线程,Local表示本地,我们就理解为线程本地变量了。想了解更多Thread,可看:快速掌握并发编程---Thread常用方法
先看看ThreadLocal的整体
最关心的三个公有方法:set、get、remove
构造方法?public?ThreadLocal()?{?}构造方法里没有任何逻辑处理,就是简单的创建一个实例。
set方法源码为
public?void?set(T?value)?{????//获取当前线程????????Thread?t?=?Thread.currentThread();????//这是什么鬼?????????ThreadLocalMap?map?=?getMap(t);????????????if?(map?!=?null)????????????????????map.set(this,?value);???????????else????????createMap(t,?value);}先看看ThreadLocalMap是个什么东东
ThreadLocalMap是ThreadLocal的静态内部类。
set方法整体为
ThreadLocalMap构造方法
//这个属性是ThreadLocal的,就是获取hashcode(这列很有学问,但是我们的目的不是他)private?final?int?threadLocalHashCode?=?nextHashCode();private?Entry[]?table;private?static?final?int?INITIAL_CAPACITY?=?16;//Entry是一个弱引用????????static?class?Entry?extends?WeakReference<ThreadLocal<?>>?{????Object?value;????Entry(ThreadLocal<?>?k,?Object?v)?{????????super(k);????????value?=?v;???????}?}ThreadLocalMap(ThreadLocal<?>?firstKey,?Object?firstValue)?{????//数组默认大小为16????table?=?new?Entry[INITIAL_CAPACITY];????//len?为2的n次方,以ThreadLocal的计算的哈希值按照Entry[]取模(为了更好的散列)????int?i?=?firstKey.threadLocalHashCode?&?(INITIAL_CAPACITY?-?1);????table[i]?=?new?Entry(firstKey,?firstValue);????size?=?1;????//设置阈值(扩容阈值)????setThreshold(INITIAL_CAPACITY);??}文章来源:《电脑编程技巧与维护》 网址: http://www.dnbcjqywh.cn/zonghexinwen/2020/1103/610.html
上一篇:编程不用程序员!低代码是炒作还是趋势?
下一篇:把C++当作第一门编程语言好吗
电脑编程技巧与维护投稿 | 电脑编程技巧与维护编辑部| 电脑编程技巧与维护版面费 | 电脑编程技巧与维护论文发表 | 电脑编程技巧与维护最新目录
Copyright © 2018 《电脑编程技巧与维护》杂志社 版权所有
投稿电话: 投稿邮箱: