25. ThreadLocal的设计理念与作用

2016/10/1 16:34 下午 posted in  Java comments

目的

多线程共享一个变量,可以通过public static的形式来实现。
每一个线程都有自己的共享变量,提出ThreadLocal正是解决这样的问题。
ThreadLocal类主要解决每个线程绑定自己的值,打个比方,类似全局的存放数据的盒子,盒子中可以存放每个线程的私有数据。

常用的方法

T get();

void set(T value);

protected T initialValue() {
        return null;
}

get()用来获取本地线程中存放的值,set()用来设置本地线程中的值。
覆盖initialValue()可以设定指定的初始值,若不设定,初始值默认为null。

线程变量是隔离的,即每个线程只能访问自己的值,他们有各自的初始值。

InheritableThreadLocal

使用InheritableThreadLocal可以继承父线程中的值,并可以通过覆盖childValue方法来修改继承的值。

示例

package com.cd.threadlocal;

public class Tools {

    public static ThreadLocalDefined<String> tl = new ThreadLocalDefined<String>();
    
    public Tools() {
        // TODO Auto-generated constructor stub
    }

}

package com.cd.threadlocal;

public class ThreadLocalDefined<T> extends ThreadLocal<Object> {

    @Override
    protected Object initialValue() {
        // TODO Auto-generated method stub
        return "OK";
    }

}

package com.cd.threadlocal;

public class ThreadA extends Thread {

    public ThreadA() {
        // TODO Auto-generated constructor stub
    }

    @Override
    public void run() {
        for(int i=0; i<10; ++i){
            if(Tools.tl.get() == null){
                System.out.println("ThreadA 1st " + Tools.tl.get());
            }
            
            System.out.println(Tools.tl.get());
            Tools.tl.set("Thread A "+ i);
        }
    }
}

package com.cd.threadlocal;

public class Main {

    public Main() {
        // TODO Auto-generated constructor stub
    }

    public static void main(String[] args) {
        
        ThreadA a = new ThreadA();
        a.start();
        
        for(int i=0; i<10; ++i){
            if(Tools.tl.get() == null){
                System.out.println("Main 1st " + Tools.tl.get());
            }
            
            System.out.println(Tools.tl.get());
            Tools.tl.set("Main Thread "+i);
        }

    }

}

运行结果

OK
OK
Main Thread 0
Thread A 0
Main Thread 1
Thread A 1
Thread A 2
Main Thread 2
Thread A 3
Main Thread 3
Thread A 4
Thread A 5
Main Thread 4
Thread A 6
Main Thread 5
Thread A 7
Main Thread 6
Thread A 8
Main Thread 7
Main Thread 8