ThreadLocal用于保存某个线程共享变量:对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量。
1、ThreadLocal.get: 获取ThreadLocal中当前线程共享变量的值。
2、ThreadLocal.set: 设置ThreadLocal中当前线程共享变量的值。
3、ThreadLocal.remove: 移除ThreadLocal中当前线程共享变量的值。
4、ThreadLocal.initialValue: ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值。
public classMyThreadLocal {private static final ThreadLocal threadLocal = new ThreadLocal() {//ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值
@OverrideprotectedObject initialValue() {
System.out.println("调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!");return null;
}
};public static voidmain(String[] args) {new Thread(new MyIntegerTask("IntegerTask1")).start();new Thread(new MyStringTask("StringTask1")).start();new Thread(new MyIntegerTask("IntegerTask2")).start();new Thread(new MyStringTask("StringTask2")).start();
}public static class MyIntegerTask implementsRunnable {privateString name;
MyIntegerTask(String name) {this.name =name;
}
@Overridepublic voidrun() {for (int i = 0; i < 5; i++) {//ThreadLocal.get方法获取线程变量
if (null ==MyThreadLocal.threadLocal.get()) {//ThreadLocal.et方法设置线程变量
threadLocal.set(0);
System.out.println("线程" + name + ": 0");
}else{int num =(Integer) MyThreadLocal.threadLocal.get();
MyThreadLocal.threadLocal.set(num+ 1);
System.out.println("线程" + name + ": " +MyThreadLocal.threadLocal.get());if (i == 3) {
MyThreadLocal.threadLocal.remove();
}
}try{
Thread.sleep(1000);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}public static class MyStringTask implementsRunnable {privateString name;
MyStringTask(String name) {this.name =name;
}
@Overridepublic voidrun() {for (int i = 0; i < 5; i++) {if (null ==MyThreadLocal.threadLocal.get()) {
MyThreadLocal.threadLocal.set("a");
System.out.println("线程" + name + ": a");
}else{
String str=(String) MyThreadLocal.threadLocal.get();
MyThreadLocal.threadLocal.set(str+ "a");
System.out.println("线程" + name + ": " +MyThreadLocal.threadLocal.get());
}try{
Thread.sleep(800);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程IntegerTask1: 0
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程StringTask1: a
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程IntegerTask2: 0
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程StringTask2: a
线程StringTask2: aa
线程StringTask1: aa
线程IntegerTask2: 1
线程IntegerTask1: 1
线程StringTask1: aaa
线程StringTask2: aaa
线程IntegerTask1: 2
线程IntegerTask2: 2
线程StringTask1: aaaa
线程StringTask2: aaaa
线程IntegerTask2: 3
线程IntegerTask1: 3
线程StringTask1: aaaaa
线程StringTask2: aaaaa
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程IntegerTask1: 0
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程IntegerTask2: 0
在实现应用程序框架时,大量使用了ThreadLocal。J2EE容器需要将一个事务上下文与某个执行中的线程关联起来。通过将事务上下文保存在静态的ThreadLocal对象中很容易实现这个功能。它避免了在调用每个方法时都需要传递执行上下文信息。
除非这个操作的执行频率很高,或者分配操作的开销很高,否则这个技术不可能带来性能提升。