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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值