ThreadLocal 是为了更好的写多线程,而使用的变量,个人理解不是通常利用ThreadLocal变量来处理线程同步关系的。而是为了方便书写代码。
参考了博文:原博文 ,我又将其冗余的部分修改了,为了更好理解,下面做一些必要的说明。
总共有三个类:mmain.java SQLSearch.java ThreadLocalUtils.java
mmain.java 就是java的运行主类(包含main的方法),SQLSearch.java 是为了获取到调用该方法所对应的线程变量,并显示信息。 ThreadLocalUtils.java 定义了用来保存各个线程所持有变量的集合。
源码如下:
ThreadLocalUtils.java
public class ThreadLocalUtils{
public static final ThreadLocal<String> DATA = new ThreadLocal<String>();
}
SQLSearch.java
public class SQLSearch{
public String run(){
return search(ThreadLocalUtils.DATA.get()); //将会获得对应的线程的String对象,也就是在ThreadLocal尖括号之间的类型
}
private String search(String name){
String result = null;
if(name.equals("S")){
result = (name+":165");
}
if(name.equals("M")){
result = (name+":170");
}
if(name.equals("L")){
result = (name+":175");
}
if(name.equals("XL")){
result = (name+":180");
}
if(name.equals("XXL")){
result = (name+":185+");
}
return result;
}
}
mmain.java :
public class mmain{
static String[] names = new String[]{"S","M","L","XL","XXL"}; //衣服的尺码
static int index = 0; //为了分别设置线程名称
public static void main(String args[]){
for(int i = 0; i < names.length; i++){
Thread t = new Thread(){
public void run(){
ThreadLocalUtils.DATA.set(this.getName()); //设置当前线程的名称
System.out.println(new SQLSearch().run()); //利用SQLSearch中run方法获取到当前线程的线程名
}
};
t.setName(names[index++]); //将尺码的名称依次设置为线程名
t.start(); //启动线程
}
}
}
执行的结果如下:
sely@com:~/sylinux/ThreadLocal$ java mmain
S:165
M:170
L:175
XL:180
XXL:185+
代码执行的流程:
1. 执行main函数,进入for循环,生成了第一个thread()
2. 设置第一个thread的线程名,index为0,所以设置的线程名为“S”
3. 执行线程的start方法,就会调用run()方法,也就是重写的run方法体,方法体执行了ThreadLocalUtils.DATA.set(this.getName());
DATA是static属性,属于ThreadLocalUtils这个类的,不属于任何它的实例化对象所有,可以用类名.属性名的方法直接调用。DATA这个变量是ThreadLocal对象,
<T>之间就是这个变量所保存的数据类型。
4. ThreadLocal<T>类提供了一下的方法:
T get() : Returns the value in the current thread's copy of this thread-local variable.
protected T initialValue() : Returns the current thread's "initial value" for this thread-local variable.
void remove() : Removes the current thread's value for this thread-local variable.
void set(T value) : Sets the current thread's copy of this thread-local variable to the specified value.
5. 代码利用DATA.set()方法,就会将当前线程的名称(String类型)设置到DATA中去,调用set的线程,此时就是第一个创建的线程,所以set进DATA就是“S”
6. 第二次利用set()方法又会设置当前线程名, 这时同样调用的是第二个线程的getName(),设置到DATA中。
.........
7. 设置过程中,又利用new SQLSearch()对象的run方法,来取出它保存在DATA中的String,调用 ThreadLocalUtils.DATA.get()方法,就会获得调用这个方法所属于线程开始设置的变量。跟set差不多,所以每次get都能够区分开线程所拥有的值了。