【多线程】类ThreadLocal的使用


类ThreadLocal主要解决的就是每个线程绑定自己的值,可以将ThreadLocal类比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。
变量在不同线程间具有隔离性,也就是不同线程拥有自己的值,不同线程中的值是可以放入ThreadLocal类中进行保存的。
下面代码来验证线程变量的隔离性:

public class Test {

    public static void main(String[] args) {
        try {
            ThreadA a = new ThreadA();
            a.start();
            
            Thread.sleep(2000);
            
            ThreadB b = new ThreadB();
            b.start();
            
            Thread.sleep(2000);
            
            if (Tools.threadLocal.get() == null) {
                Tools.threadLocal.set(new Date());
            }
            System.out.println("   Main get value " + Tools.threadLocal.get());
        } catch (InterruptedException ex) {
            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

class ThreadA extends Thread {
    @Override
    public void run() {
        try {
            if (Tools.threadLocal.get() == null) {
                Tools.threadLocal.set(new Date());
            }
            System.out.println("ThreadA get value " + Tools.threadLocal.get());
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(ThreadA.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

class ThreadB extends Thread {
    @Override
    public void run() {
        try {
            if (Tools.threadLocal.get() == null) {
                Tools.threadLocal.set(new Date());
            }
            System.out.println("ThreadB get value " + Tools.threadLocal.get());
            Thread.sleep(100);
        } catch (InterruptedException ex) {
            Logger.getLogger(ThreadA.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

class Tools {
    static ThreadLocal<Date> threadLocal = new ThreadLocal<Date>();
}

控制台打印结果如下:
ThreadA get value Fri Apr 07 16:00:59 CST 2017
ThreadB get value Fri Apr 07 16:01:01 CST 2017
   Main get value Fri Apr 07 16:01:03 CST 2017


虽然3个线程都向threadLocal中set()数据值,但是每个线程还是能取出自己的数据。
在第一次调用ThreadLocal类的get()方法返回值是null,怎么样实现第一次调用get()不反悔null呢?也就是具有默认值的效果。
修改一下内部类Tools :

class Tools {
    static ThreadLocalExt<Date> threadLocal = new ThreadLocalExt<Date>();
}

class ThreadLocalExt<V> extends ThreadLocal{
    @Override
    protected Object initialValue() {
        return "Default value";
    }
}


控制台打印结果如下:

ThreadA get value Default value
ThreadB get value Default value
   Main get value Default value


可见覆盖ThreadLocal类的initialValue()方法可以设置默认值。

猜你喜欢

转载自margaret0071.iteye.com/blog/2367815