在java中,如果多个线程想要用到一个共享的变量,那么可以用public static修饰这个变量,所有的线程使用同一个static变量。如果想要实现每一个线程都有自己的共享变量,该怎么解决呢?JDK中的ThreadLocal就是为此而生的!下面我们来看几个例子来理解ThreadLocal在多线程的独立性。
ThreadLocal的初始值
public class Run {
//ThreadLocal的初始值为null
public static ThreadLocal t1 =new ThreadLocal();
public static void main(String args[]){
System.out.println("ThreadLocal的默认值:"+t1.get());
if(t1.get() == null){
t1.set(11);
}
System.out.println("设置后的值:"+t1.get());
}
}
公用类
public class ToolsExt extends ThreadLocal {
/**
* 该方法可以对ThreadLocal进行初始化
* @return
*/
@Override
protected Object initialValue() {
return new Date().getTime();
}
}
public class Tools {
public static ThreadLocal t1 = new ThreadLocal();
public static ThreadLocal<Date> tDate = new ThreadLocal();
public static ToolsExt te=new ToolsExt();
}
样例一
public class ThreadA extends Thread {
@Override
public void run() {
for(int i=0;i<100;i++){
Tools.t1.set(i);
System.out.println("ThreadA get value="+Tools.t1.get());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadB extends Thread {
@Override
public void run() {
for(int i=0;i<100;i++){
Tools.t1.set(i);
System.out.println("ThreadB get value="+Tools.t1.get());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String args[]) throws InterruptedException {
ThreadA threadA = new ThreadA();
ThreadB threadB = new ThreadB();
threadA.start();
threadB.start();
for(int i=0;i<100;i++){
Tools.t1.set(i);
System.out.println("main get value="+Tools.t1.get());
Thread.sleep(100);
}
}
这里给出部分的结果
ThreadA get value=85
ThreadB get value=86
main get value=86
ThreadA get value=86
ThreadB get value=87
main get value=87
ThreadA get value=87
ThreadB get value=88
main get value=88
ThreadA get value=88
main get value=89
ThreadB get value=89
ThreadA get value=89
ThreadB get value=90
main get value=90
ThreadA get value=90
main get value=91
ThreadB get value=91
ThreadA get value=91
ThreadA get value=92
ThreadB get value=92
main get value=92
ThreadA get value=93
ThreadB get value=93
main get value=93
main get value=94
ThreadA get value=94
ThreadB get value=94
ThreadA get value=95
main get value=95
ThreadB get value=95
ThreadA get value=96
ThreadB get value=96
main get value=96
main get value=97
ThreadB get value=97
ThreadA get value=97
ThreadA get value=98
main get value=98
ThreadB get value=98
ThreadB get value=99
main get value=99
ThreadA get value=99
显而易见的是每个线程都有自己独立的一份值
样例二
public class ThreadDateA extends Thread {
@Override
public void run() {
for(int i=0;i<5;i++){
if(Tools.tDate.get() == null){
Tools.tDate.set(new Date());
}
System.out.println("Atime:"+Tools.tDate.get().getTime());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadDateB extends Thread {
@Override
public void run() {
for(int i=0;i<5;i++){
if(Tools.tDate.get() == null){
Tools.tDate.set(new Date());
}
System.out.println("Btime:"+Tools.tDate.get().getTime());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String args[]) throws InterruptedException {
ThreadDateA threadDateA = new ThreadDateA();
ThreadDateB threadDateB = new ThreadDateB();
threadDateA.start();
Thread.sleep(100);
threadDateB.start();
Thread.sleep(100);
for(int i=0;i<5;i++){
if(Tools.tDate.get()== null){
Tools.tDate.set(new Date());
}
System.out.println(" mainTime:"+Tools.tDate.get().getTime());
}
}
结果
Atime:1527696144164
Atime:1527696144164
Btime:1527696144276
Btime:1527696144276
mainTime:1527696144384
Atime:1527696144164
mainTime:1527696144384
mainTime:1527696144384
mainTime:1527696144384
mainTime:1527696144384
Btime:1527696144276
Atime:1527696144164
Atime:1527696144164
Btime:1527696144276
Btime:1527696144276
样例三
public class ThreadDateC extends Thread {
@Override
public void run() {
for(int i=0;i<5;i++){
System.out.println("ThreadC:"+Tools.te.get());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String args[]) throws InterruptedException {
ThreadDateC threadDateC = new ThreadDateC();
threadDateC.start();
for(int i=0;i<5;i++){
System.out.println(" main:"+Tools.te.get());
Thread.sleep(100);
}
}
结果就更具代表性了
main:1527696246693
ThreadC:1527696246694
main:1527696246693
ThreadC:1527696246694
main:1527696246693
ThreadC:1527696246694
main:1527696246693
ThreadC:1527696246694
main:1527696246693
ThreadC:1527696246694