在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