ThreadLocal是为每一个线程创建一个单独的变量副本,故而每个线程都可以独立地改变自己所拥有的变量副本,而不会影响其他线程所对应的副本。ThreadLocal并不是一个Thread,而是Thread的一个局部变量。
ThreadLocal定义了四个方法:
- get():返回此线程局部变量的当前线程副本中的值。
- initialValue():返回此线程局部变量的当前线程的“初始值”。
- remove():移除此线程局部变量当前线程的值。
- set(T value):将此线程局部变量的当前线程副本中的值设置为指定值。
ThreadLocal实例本身是不存储值,它只是提供了一个在当前线程中找到副本值得key。
是ThreadLocal包含在Thread中,而不是Thread包含在ThreadLocal中。
可以自己尝试简单的实现一个ThreadLocal
public class SeqCount<T> {
private Map<Thread,T> threadMap=new HashMap<>();
public void set(T value){
threadMap.put(Thread.currentThread(),value);
}
public T initialValue(){
return null;
}
public T get(){
Thread currentThread =Thread.currentThread();
T o = threadMap.get(currentThread);
if(o==null&&!threadMap.containsKey(currentThread)){
o=initialValue();
threadMap.put(currentThread,o);
}
return o;
}
public void remove(){
threadMap.remove(Thread.currentThread());
}
public static void main(String[] args) {
SeqCount<Integer> threadLocal=new SeqCount<>();
new Thread(()->{
threadLocal.set(1);
System.out.println(Thread.currentThread().getName());
System.out.println(threadLocal.get());
}).start();
new Thread(()->{
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
threadLocal.set(10);
System.out.println(Thread.currentThread().getName());
System.out.println(threadLocal.get());
}).start();
}
}
返回:
Thread-0
1
Thread-1
10
private static class Count implements Runnable{
//共有50张车票
//private int num = 50;
private static ThreadLocal<Integer> num1 = new ThreadLocal<Integer>(){
@Override
public Integer initialValue() {
return 50;
}
};
public int nextSeq(){
num1.set(num1.get() - 1);
return num1.get();
}
@Override
public void run() {
for (int i = 0; i < 50; i++) {
if (num1.get() > 0) {
try {
//模拟网络延迟
Thread.sleep(100);
int a=num1.get();
System.out.println(Thread.currentThread().getName() + "第"
+ a-- + "号");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
// public static void main(String[] args) {
//
// Runnable count= new Count();
// new Thread(count,"A").start();
// new Thread(count,"B").start();
// new Thread(count,"C").start();
// }
返回是
a 50------0;
b 50------0;
c 50------0;
参考文章