ThreadLocal 就是部分变量 几个线程要同时来访问 为了保证数据的安全性 简单的理解就是一个大大的 map<thread,value>
我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全的“状态性对象”采用ThreadLocal进行封装,让它们也成为线程安全的“状态性对象”,因此有状态的Bean就能够以singleton的方式在多线程中正常工作了。
示例代码
package com.hw.sync;
/**
* Created by Administrator on 2018/5/9.
*/
public class UseThreadLocal {
//可以理解为 一个map,类型 Map<Thread,Integer>
static ThreadLocal<Integer> threadLaocl = new ThreadLocal<Integer>(){
@Override
protected Integer initialValue() {
return 1;
}
};
/**
* 运行3个线程
*/
public void StartThreadArray(){
Thread[] runs = new Thread[3];
for(int i=0;i<runs.length;i++){
runs[i]=new Thread(new TestThread(i));
}
for(int i=0;i<runs.length;i++){
runs[i].start();
}
}
// ThreadLocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,
// 减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。举个例子,我出门需要先坐公交再做地铁,
// 这里的坐公交和坐地铁就好比是同一个线程内的两个函数,我就是一个线程,我要完成这两个函数都需要同一个东西:
// 公交卡(北京公交和地铁都使用公交卡),那么我为了不向这两个函数都传递公交卡这个变量(相当于不是一直带着公交卡上路),
// 我可以这么做:将公交卡事先交给一个机构,当我需要刷卡的时候再向这个机构要公交卡(当然每次拿的都是同一张公交卡)。
// 这样就能达到只要是我(同一个线程)需要公交卡,何时何地都能向这个机构要的目的。有人要说了:你可以将公交卡设置为全局变量啊,
// 这样不是也能何时何地都能取公交卡吗?但是如果有很多个人(很多个线程)呢?大家可不能都使用同一张公交卡吧
// (我们假设公交卡是实名认证的),这样不就乱套了嘛。现在明白了吧?这就是ThreadLocal设计的初衷:提供线程内部的局部变量,
// 在本线程内随时随地可取,隔离其他线程。
/**
*类说明:测试线程,线程的工作是将ThreadLocal变量的值变化,并写回,看看线程之间是否会互相影响
*/
public static class TestThread implements Runnable{
int id;
public TestThread(int id){
this.id = id;
}
public void run() {
System.out.println(Thread.currentThread().getName()+":start");
Integer s = threadLaocl.get();//获得变量的值
s = s+id;
threadLaocl.set(s);
System.out.println(Thread.currentThread().getName()+":" +threadLaocl.get());
//threadLaocl.remove();
}
}
public static void main(String[] args){
UseThreadLocal test = new UseThreadLocal();
test.StartThreadArray();
}
}