3.5线程变量私有
如果需要线程间进行变量共享,可以把变量定义为 public static.
如果需要线程内部的变量共享,可以使用 ThreadLocal.
public static ThreadLocal t = new ThreadLocal();
ThreadLocal 具有 get() 和 set() 方法,不同线程拥有自己的域。
子线程MyThread.java
public class MyThread extends Thread{
@Override
public void run(){
if (Run.t.get()==null){
System.out.println("无");
Run.t.set("子线程数据");
}
System.out.println(Run.t.get());
}
}
主线程 Run.java
public class Run {
public static ThreadLocal t = new ThreadLocal();
public static void main(String[] args) {
MyThread s = new MyThread();
s.start();
if (t.get() == null){
System.out.println("未有值");
t.set("Hi");
}
System.out.println(t.get());
}
运行结果
未有值
Hi
无
子线程数据
这表明,不同线程去访问同一静态域 t,所得到的内容是不一样的。每个线程只能取得属于自己的那一份。
可以继承 ThreadLocal 并且重写值初始化方法。
public class MyThreadLocal extends ThreadLocal{
@Override
protected Object initialValue(){
return "fine";
}
}
public static ThreadLocal t = new InheritableThreadLocal();
当前线程的值,第一次访问(set 或者 get)之后才生效,才可被继承。
-
父线程的值被访问过之后,子线程可以继承父线程的值,但子线程值修改(set)对父线程没有影响。
-
若父线程的值未被访问,子线程访问所得到的值是默认值。
子线程访问到的是默认值
public class Run { public static ThreadLocal t = new MyInheritableThreadLocal(); public static void main(String[] args) throws InterruptedException { MyThread s = new MyThread(); s.start(); } }
运行结果
fine
父线程的值有被访问,则子线程会继承
public class Run { public static ThreadLocal t = new MyInheritableThreadLocal(); public static void main(String[] args) throws InterruptedException { System.out.println(t.get());//父线程的值有被访问 MyThread s = new MyThread(); s.start(); } }
运行结果
fine
fineHa -
父线程修改了值,并且执行了其他语句之后,子线程再来继承所得到的值就是新的值。
-
如果在子线程获取值的时候,父线程修改了值,那么子线程获取到的是旧的值。
-
若想要在继承的同时对子线程的值进行修改,可以重写 childValue 方法。
MyInheritableThreadLocal.java
public class MyInheritableThreadLocal extends InheritableThreadLocal{ @Override protected Object initialValue(){ return "fine"; } @Override protected Object childValue(Object parentValue){ return parentValue + "Ha"; } }