1、直接上我的程序
思路一:设置一个普通的静态ThreadLocal属性
// ①通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值
private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {
public Integer initialValue() {
return 0;
}
};
思路二:设置一个静态的Integer属性
static Integer seqNum=0; //方案二
我的代码程序
package com.books.tool.test;
public class TestNum {
// ①通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值
// private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {
// public Integer initialValue() {
// return 0;
// }
// };
static Integer seqNum=0; //方案二
private static class TestClient extends Thread {
private TestNum sn;
public TestClient(TestNum sn) {
this.sn = sn;
}
public void run() {
for (int i = 0; i < 3; i++) {
// ④每个线程打出3个序列值
System.out.println("thread[" + Thread.currentThread().getName() + "] --> sn["
+ sn.getNextNum() + "]"); //方法getNextNum是对象的方法,操作的变量却是seqNum(ThreadLocal<Integer>)静态变量
}
}
}
// ②获取下一个序列值
public int getNextNum() {
//seqNum是TestNum的静态变量,ThreadLocal自带get方法
// seqNum.set(seqNum.get() + 1);
// return seqNum.get();
seqNum=seqNum+1; //方案二
return seqNum; //方案二
}
public static void main(String[] args) {
TestNum sn = new TestNum();
// ③ 3个线程共享sn,各自产生序列号
TestClient t1 = new TestClient(sn);
TestClient t2 = new TestClient(sn);
TestClient t3 = new TestClient(sn);
t1.start();
t2.start();
t3.start();
}
}
2、实验结果
a)用ThreadLocal的输出为
b)用Integer的输出为
3、总结
- 普通的静态属性会和其他线程共用,同时存在线程安全问题
- ThreadLocal 静态属性不会和其他线程共用,每个线程都有独立的ThreadLocal
参考文档:
1、彻底理解ThreadLocal