关于threadLocal的使用

来源:互联网 发布:八音盒制作软件 编辑:程序博客网 时间:2024/05/21 21:29

threadLocal主要是为我们创建一个资源副本,
protected Object initialValue()

返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal。API方法也相应进行了调整,新版本的API方法分别是void set(T value)、T get()以及T initialValue()。

ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单:在ThreadLocal类中定义了一个ThreadLocalMap,每一个Thread中都有一个该类型的变量——threadLocals——用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本。———————————以上内容来自搜狗百科
可以理解的就是使用threadLocal时,本质是创建了一个map集合,只是里面的键不需要我们进行赋值,而是每个线程的hash码,而且在这个集合中,是支持泛型的,我们使用时,是先在主函数中复写initialValue。然后是在进程方法中,调用get/set方法来使用
目的是创建资源副本,也是为了解决线程安全而使用

ThreadLocal和其它所有的同步机制都是为了解决多线程中的对同一变量的访问冲突,在普通的同步机制中,是通过对象加锁来实现多个线程对同一变量的安全访问的。这时该变量是多个线程共享的,使用这种同步机制需要很细致地分析在什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放该对象的锁等等很多。所有这些都是因为多个线程共享了资源造成的。ThreadLocal就从另一个角度来解决多线程的并发访问,ThreadLocal会为每一个线程维护一个和该线程绑定的变量的副本,从而隔离了多个线程的数据,每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的整个变量封装进ThreadLocal,或者把该对象的特定于线程的状态封装进ThreadLocal。

实例代码:
在线程类中,初始化threadLocal,然后在run方法中,使用get/set方法

public class RunableDemo implements Runnable{    private int ticket;    private ThreadLocal<Integer>threadLocal;    public RunableDemo(ThreadLocal<Integer>threadLocal) {        this.threadLocal=threadLocal;    }    @Override    public void run() {        ticket=threadLocal.get();        for(int i=0;i<=5;i++){            ticket++;        }        threadLocal.set(ticket);        System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());    }}

在主函数中,可以看出是使用了匿名内部类;来复写inimicalValuefnagfa

public class CoreJava01 {    public static void main(String[] args) {        ThreadLocal<Integer>threadLocal=new ThreadLocal<Integer>(){            @Override            protected Integer initialValue() {                return 300;            }        };        RunableDemo runableDemo=new RunableDemo(threadLocal);        Thread[] threads=new Thread[6];        for(int i=0;i<=5;i++){            threads[i]=new Thread(runableDemo);        }        for(Thread thread:threads){            thread.start();        }    }}
0 0
原创粉丝点击