对线程本地ThreadLocal的理解

在java中,变量的共享可以使用Public static 变量的形式进行声明,所有的线程都可以使用被Public static 声明的变量。但如果我们想要每一个线程都有自己的共享变量?(换个角度讲,每一个线程中的变量名相同而引用的值不一样)。JDK提供了ThreadLocal用于解决这样的问题。

举个例子:

public class ThreadLocalDemo {

    public ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

    public void setThreadLocal(Integer number){
        threadLocal.set(number);
    }

    public void getThreadLocal(){
        System.out.println(Thread.currentThread().getName()+":"+threadLocal.get());
    }

    public static void main(String[] args){
        ThreadLocalDemo demo = new ThreadLocalDemo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                demo.setThreadLocal(10);
                demo.getThreadLocal();
            }
        },"th1").start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                demo.setThreadLocal(5);
                demo.getThreadLocal();
            }
        },"th2").start();
    }
}

运行结果:


可见,虽然多个线程对threadLocal这个变量进行访问,但由于threadLocal被ThreadLocal所修饰,不同线程访问的是本身线程设置的值。实际上ThreadLocal为每一个使用该变量的线程创建了一个副本,线程访问的是自己的副本而不会受其他线程副本的影响。实现的思路在threadLocal中有一个static的Map,其中key为线程,value为对应的副本。

ThreadLocal与Synchronized的比较:

  • 在同步机制中,Synchronized采用了锁机制保证了同一时刻只有一个线程访问变量。ThreadLocal没有采用锁机制,而是以空间换时间的方式,为每个线程创建独立的副本来保证线程的安全。
  • 采用锁机制,需要慎密的考虑需要锁定什么对象,什么时候进行锁定以及什么时候进行锁的释放,在程序设计和编写上变得偏复杂

猜你喜欢

转载自blog.csdn.net/hsf15768615284/article/details/78301868
今日推荐