ThreadLocal原理-编程思维

一、Thread

public class Thread(){
    //省略部分
    
    //属于这个线程的ThreadLocals,这个map由ThreadLocal类维护
    ThreadLocal.ThreadLocalMap threadLocals = null;
    
    //省略部分
}

二、ThreadLocal

public class ThreadLocal(){
 //省略部分
    
//set操作
public void set(T value) {
        //当前调用set方法的线程
        Thread t = Thread.currentThread();
        //获取当前调用线程的ThreadLocalMap
        ThreadLocalMap map = getMap(t);
        if (map != null)
            //this 为静态的一个自定义的ThreadLocal对象的引用,map存在则set
            map.set(this, value);
        else
            //map 不存在则新建
            createMap(t, value);
    }
    
     // new 一个ThreadLocalMap
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }
    
// get操作
public T get() {
    
        //当前调用get方法的线程
        Thread t = Thread.currentThread();
        //获取当前线程的ThreadLocalMap
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            //this 为静态的一个自定义的ThreadLocal对象的引用
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
    
 //省略部分
}

三、小结

  • 每个线程对象都有一个自己的ThreadLocalMap类对象,由ThreadLocal对象维护,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。

  • 将一个共用的ThreadLocal静态实例(通常在需要的方法中自定义)作为key,将不同值对象的引用保存到不同线程的ThreadLocalMap中,然后在线程执行的各处通过这个静态ThreadLocal实例的get()方法取得自己线程保存的那个对象

四、使用场景

  • session问题配合Filter一起使用
  • 多数据源配置,通过配置当前线程的datasoure信息

版权声明:本文版权归作者所有,遵循 CC 4.0 BY-SA 许可协议, 转载请注明原文链接
https://www.cnblogs.com/geekdc/p/13533411.html

java8新特性-lambda表达式和stream API的简单使用-编程思维

一、为什么使用lambda   Lambda 是一个 匿名函数,我们可以把 Lambda表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。 package com.duchong.java8; /** * @

创建线程的第三种方式以及简单使用-编程思维

一、Callable接口   与继承Thread和实现Runnable接口方式创建线程相比,有以下两点不同: 可以有返回值,并且能够获取返回值 call()方法允许抛出异常 二、简单使用 package com.duchong.thread.callable; import java.util.concurre

Volatile关键字以及线程的内存可见性问题-编程思维

一、Volatile关键字 作用: 当多个线程进行操作共享数据时,可以保证内存中的数据可见,即为一个线程对数据的修改对另外一个线程来说是可见的。相较于 synchronized 是一种较为轻量级的同步策略。但不保证互斥可原子性。 二、简单使用 package com.duchong.juc; public clas

java中动态代理-编程思维

一、在java中怎样实现动态代理   1、我们要有一个接口,还要有一个接口的实现类,而这个实现类呢就是我们要代理的对象 接口: 1 package org.dynamicproxy.test; 2 3 public interface UserDao { 4 public void addUser(User

Object和String-编程思维

一、Object类 package java.lang; public class Object { private static native void registerNatives(); static { registerNatives(); } //获取class

Android: 录音-编程思维

Android录音 /** * 开始录音 */ private void startRecording() { mRecorder = new MediaRecorder(); mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

i++的原子性问题-编程思维

一、什么是原子性   简单的可以理解为:操作是不可再分割的,比如; int i=0; 但是i++的操作是可以再分的,比如: i++ //分解后 i=i+i 上面的代码在多线程环境下取值是有问题的,比如: package com.example.demo.juc; /** * @author DUCHON

利用同步辅助类CountDownLatch计算多线程的运行时间-编程思维

一、CountDownLatch   jdk提供的一个同步辅助类,在完成一组在在其他线程中执行的操作前,允许一个或者多个其他的线程等待,通过调用 await() 方法阻塞,直到由于 countDown() 方法的调用而导致当前计数达到零,之后所有等待线程被释放。 二、计算多个线程执行时间 package com.ex

volatile底层实现原理-编程思维

内存屏障 原文地址 作者:Martin Thompson 译者:一粟 校对:无叶,方腾飞 本文我将和大家讨论并发编程中最基础的一项技术:内存屏障或内存栅栏,也就是让一个CPU处理单元中的内存状态对其它处理单元可见的一项技术。 CPU使用了很多优化技术来实现一个目标:CPU执行单元的速度要远超主存访问速度。在上一篇文章

java并发锁-编程思维

序号 锁名称 应用 1 乐观锁 CAS 2 悲观锁 synchronized、vector、hashtable 3 自旋锁 CAS 4 可重入锁 synchronized、Reentrantlock、Lock 5 读写锁 ReentrantReadWriteLock,CopyOnWriteArr