一、ThreadLocal
类ThreadLocal主要解决的是每个线程绑定自己的值,把ThreadLocal类比喻成全局存放数据的盒子,盒子中可以存储每个线程的私有数据。
在第一次调用ThreadLocal类的get()方法时返回值为null,解决方法以及验证线程变量的隔离性如下代码。
Tools.java
public class Tools {
public static ThreadLocalExtend t1=new ThreadLocalExtend();
}
ThreadLocalExtend.java
public class ThreadLocalExtend extends ThreadLocal{
protected Object initialValue() {
return "我是默认值,我不是null";
}
}
ThreadA.java
public class ThreadA extends Thread{
public void run(){
try{
for(int i=0;i<5;i++){
System.out.println("A="+Tools.t1.get());
Thread.sleep(100);
}
}catch(InterruptedException e){
}
}
}
Run.java
public class Run {
public static void main(String[] args) throws InterruptedException{
for(int i=0;i<5;i++){
System.out.println("main="+Tools.t1.get());
Thread.sleep(100);
}
Thread.sleep(5000);
ThreadA a=new ThreadA();
a.start();
}
}
结果如下:
二、InheritableThreadLocal
类InheritableThreadLocal可以在子线程中取得父线程继承下来的值,而且继承下来的数值还能改变。
Tools.java
public class Tools {
public static InheritableThreadExtend t1=new InheritableThreadExtend();
}
InheritableThreadExtend.java
/*
* 子线程能从主线程中取得值
* 子线程从主线程取值并修改
*/
public class InheritableThreadExtend extends InheritableThreadLocal{
protected Object initialValue(){
return new Date().getTime();
}
protected Object childValue(Object parentValue){
return parentValue+" 我在子线程";
}
}
ThreadA.java
public class ThreadA extends Thread{
public void run(){
try{
for(int i=0;i<5;i++){
System.out.println("ThreadA: "+Tools.t1.get());
Thread.sleep(100);
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
Run.java
public class Run {
public static void main(String[] args) throws InterruptedException{
for(int i=0;i<5;i++){
System.out.println("main= "+Tools.t1.get());
Thread.sleep(100);
}
Thread.sleep(5000);
ThreadA a=new ThreadA();
a.start();
}
}
结果如下: