1.ThreadLocal
JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal并不是一个Thread,而是Thread的局部变量。
2.ThreadLocal 涉及方法
T | get() 返回当前线程的值 |
protected T | initialValue() 初始化当前线程的值,如果第一次没有set之间get这个时候拿出的就是在这里初始化的值 |
void | remove() 删除当前线程的值 |
void | set(T value) 为当前线程福祉 |
3.源码介绍
ThreadLocal相当于map{this.currentThread,var},类似通过当前线程的key,来取的自己的变量,这样每个变量都有自己的一份共享变量,彼此之间不会干扰,下面是他的set(T value)源码介绍:
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
第一次会判断map有没有值,如果没有才进行创建,所以彼此之间不会产生影响
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
首先如果map不等于null,就返回当前线程的值,如果等于null 这里就返回初始化值
4. 下面自己写的例子
private Integer ticketNum=5;
private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {
public Integer initialValue() {
return 0;
}
};
public Integer getNextNum()
{
seqNum.set(seqNum.get()+1);
return seqNum.get();
}
@Override
public void run() {
for(int i=0;i<6;i++)
{
if(ticketNum>0)
{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Integer tmpNum=this.ticketNum--;
System.out.println(Thread.currentThread().getName()+"号线程的值---〉"+getNextNum());
}
}
}
public static void main(String[] args) {
SecondRunnable my = new SecondRunnable();
new Thread(my, "1").start();
new Thread(my, "2").start();
new Thread(my, "3").start();
}
运行结果如下:
1号线程的值---〉1
2号线程的值---〉1
3号线程的值---〉1
3号线程的值---〉2
1号线程的值---〉2
2号线程的值---〉2
3号线程的值---〉3
2号线程的值---〉3
1号线程的值---〉3
3号线程的值---〉4
2号线程的值---〉4
1号线程的值---〉4
1号线程的值---〉5
2号线程的值---〉5
3号线程的值---〉5
2号线程的值---〉6
1号线程的值---〉6
3号线程的值---〉6
简单小节结束