JAVA之ThreadLocal

在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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章