threadlocal

JAVA ThreadLocal对象浅析

亡梦爱人 提交于 2021-01-21 22:22:45
最近在开发过程中,在做一个字典项服务的时候,最开始采用了ThreadLocal对象来缓存数据。在使用ThreadLocal过程中遇到一些问题,这里和大家分享一下。 一、 什么是 ThreadLocal ? 顾名思义它是local variable(线程局部变量)。它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本。从线程的角度看,就好像每一个线程都完全拥有该变量。 它主要由四个方法组成initialValue(),get(),set(T),remove(),其中initialValue()方法是一个protected的方法,只有在重写ThreadLocal的时候有用。 void set(T t):为调用该方法的线程存入一个本线程变量。 T get(): 返回本线程存入ThreadLocal中的值,没有返回空。 void remove(): 移除本线程存入ThreadLocal中的值。 T initialValue():用于在为null时,生成一个初始值,ThreadLocal直接返回一个null值。 二、 ThreadLocal 的原理 在查看了java源码后发现,ThreadLocal通过使用ThreadLocalMap(注:这里的Map非java.util.Map子类)实例来存储”线程局部变量”,当第一次设值的时候,如果map为空,则创建一个map并set入值

ThreadLocal与其他变量的区别

断了今生、忘了曾经 提交于 2020-04-07 16:28:36
今天学习了ThreadLocal,一直不知道它的用法,所以自己花时间写了个demo来理清楚ThreadLocal修饰的成员变量和类的普通成员的区别。 其实很简单,使用ThreadLocal<T>变量,一定要用public static来修饰,它的作用域是和public static修饰的普通变量一致的,但是普通变量是所有类共享的,而public static ThreadLocal<T>变量是每个线程自己私有的,并且可以在线程执行的过程中,随时获取,随时增删改,一直到线程执行完毕被销毁。 ThreadLocal是一个JAVA类,ThreadLocalMap是它的内部静态类。 ThreadLocalMap是一个定制的Map,它的key就是ThreadLocal本身,但是是弱引用的,value则是我们要保存的对象。 static class ThreadLocalMap { /** * The entries in this hash map extend WeakReference, using * its main ref field as the key (which is always a * ThreadLocal object). Note that null keys (i.e. entry.get() * == null) mean that the key is no

【每周一讲】Java的ThreadLocal

喜你入骨 提交于 2020-04-07 05:04:38
1、初识她 她到底是谁? 姑且先看个例子。 public interface Counter { /** * 获取下一个序列值 * @return */ int getNextNum(); } public class SimpleCounter implements Counter { private int i = 0; @Override public int getNextNum() { return i++; } } public class TestCounter extends Thread { private Counter counter; public TestCounter(Counter counter) { this.counter = counter; } public void run() { for (int i = 0; i < 3; i++) { // ④每个线程打出3个序列值 System.out.println("thread[" + Thread.currentThread().getName() + "] --> count[" + counter.getNextNum() + "]"); } } /** * 测试多个线程处理共享对象的情况 * 使用ThreadLocal的方式,每个线程拥有各自独立的数据拷贝。即时同一个对象 *

一文搞懂 ThreadLocal 原理

拟墨画扇 提交于 2020-04-06 17:43:21
当多线程访问共享可变数据时,涉及到线程间同步的问题,并不是所有时候,都要用到共享数据,所以就需要线程封闭出场了。 数据都被封闭在各自的线程之中,就不需要同步,这种通过将数据封闭在线程中而避免使用同步的技术称为 线程封闭 。 本文主要介绍线程封闭中的其中一种体现:ThreadLocal,将会介绍什么是 ThreadLocal;从 ThreadLocal 源码角度分析,最后介绍 ThreadLocal 的应用场景。 什么是 ThreadLocal? ThreadLocal 是 Java 里一种特殊变量,它是一个线程级别变量,每个线程都有一个 ThreadLocal 就是每个线程都拥有了自己独立的一个变量,竞态条件被彻底消除了,在并发模式下是绝对安全的变量。 可以通过 ThreadLocal<T> value = new ThreadLocal<T>(); 来使用。 会自动在每一个线程上创建一个 T 的副本,副本之间彼此独立,互不影响,可以用 ThreadLocal 存储一些参数,以便在线程中多个方法中使用,用以代替方法传参的做法。 下面通过例子来了解下 ThreadLocal: public class ThreadLocalDemo { /** * ThreadLocal变量,每个线程都有一个副本,互不干扰 */ public static final ThreadLocal

ThreadLocal

混江龙づ霸主 提交于 2020-04-05 22:12:10
什么是ThreadLocal? 顾名思义它是local variable( 线程局部变量 )。 它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。 从线程的角度看,就好像每一个线程都完全拥有该变量。 注意 :ThreadLocal不是用来解决共享对象的多线程访问问题的。 一、多线程共享成员变量 在多线程环境下,之所以会有并发问题,就是因为不同的线程会同时访问同一个共享变量,同时进行一系列的操作。 1、例如下面的形式 // 这个意思很简单,创建两个线程,a线程对全局变量+10,b线程对全局变量-10 public class MultiThreadDemo { public static class Number { private int value = 0 ; public void increase() throws InterruptedException { // 这个变量对于该线程属于局部变量 value = 10 ; Thread.sleep( 10 ); System.out.println( "increase value: " + value); } public void decrease() throws InterruptedException { //

ThreadLocal解析

大憨熊 提交于 2020-04-05 18:50:17
ThreadLocal解析 功能 线程间保存自己的变量副本,保证线程安全 方法间传递变量 源码解析 set方法讲变量存储到跟线程相关的map中 public void set(T value) { Thread t = Thread.currentThread(); // 获取当前线程的map ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } ThreadLocalMap getMap(Thread t) { // 线程对象里面包含这个map return t.threadLocals; } get方法 public T get() { Thread t = Thread.currentThread(); // 取出对应map ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue

ThreadLocal系列(三)-TransmittableThreadLocal的使用及原理解析

流过昼夜 提交于 2020-04-03 10:33:17
上一篇: ThreadLocal系列(二)-InheritableThreadLocal的使用及原理解析 一、基本使用 首先,TTL是用来解决ITL解决不了的问题而诞生的,所以TTL一定是支持父线程的本地变量传递给子线程这种基本操作的,ITL也可以做到,但是前面有讲过,ITL在线程池的模式下,就没办法再正确传递了,所以TTL做出的改进就是即便是在线程池模式下,也可以很好的将父线程本地变量传递下去,先来看个例子: // 需要注意的是,使用TTL的时候,要想传递的值不出问题,线程池必须得用TTL加一层代理(下面会讲这样做的目的) private static ExecutorService executorService = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(2)); private static ThreadLocal tl = new TransmittableThreadLocal<>(); //这里采用TTL的实现 public static void main(String[] args) { new Thread(() -> { String mainThreadName = "main_01"; tl.set(1); executorService.execute(() -> {

ThreadLocal的进化——InheritableThreadLocal

∥☆過路亽.° 提交于 2020-03-30 02:26:20
之前有介绍过 ThreadLocal,JDK 后来针对此做了一个升级版本 InheritableThreadLocal,今天就来好好介绍下。 为什么要升级 首先我们来想想,为什么要升级?这就要说起 ThreadLocal 的功能了。 我们知道,ThreadLocal 设计初衷是为了在多线程环境下,针对每一个线程能有一个自己的副本,这样可以在一定程度上解决多线程并发修改的问题。但是,我们可以在此基础上做一个拓展,比如 context ,我们可以利用 ThreadLocal 针对每一个线程都有一个自己的上下文,一般都是写成 ThreadLocal<Context> ,这样在这个线程上做的所有修改都可以被大家利用到。 此时设想一下,假如我们新建一个子线程,那这个子线程可以获取到父线程的 context 吗?理论上希望可以达成这样的效果,实际上呢?让我们看看: public class ThreadLocalContext { private static ThreadLocal<Context> context = new ThreadLocal<>(); static class Context { String name; int value; } public static void main(String[] args) { Context context = new

ThreadLocal应用与原理

流过昼夜 提交于 2020-03-25 22:02:24
ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。是能够解决多线程的实例变量的问题。 API是这样介绍的: * This class provides thread-local variables. These variables differ from * their normal counterparts in that each thread that accesses one (via its * {@code get} or {@code set} method) has its own, independently initialized * copy of the variable. {@code ThreadLocal} instances are typically private * static fields in classes that wish to

一句话读懂Threadlocal

♀尐吖头ヾ 提交于 2020-03-25 15:13:33
3 月,跳不动了?>>> threadlocal是把ThreadLocal实例作为key,要保持的对象作为值,设置到当前线程的ThreadLocalMap 中。 因此数据是保存在当前线程中的。 ThreadLocalMap实例是作为java.lang.Thread的成员变量存储的,每个线程有唯一的一个threadLocalMap。这个map以ThreadLocal对象为key,”线程局部变量”为值,所以一个线程下可以保存多个”线程局部变量”。对ThreadLocal的操作,实际委托给当前Thread,每个Thread都会有自己独立的ThreadLocalMap实例,存储的仓库是Entry[] table;Entry的key为ThreadLocal,value为存储内容;因此在并发环境下,对ThreadLocal的set或get,不会有任何问题。 总之,ThreadLocal不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式。归纳了两点: 每个线程中都有一个自己的ThreadLocalMap类对象,可以将线程自己的对象保持到其中,各管各的,线程可以正确的访问到自己的对象。 将一个共用的ThreadLocal静态实例作为key,将不同对象的引用保存到不同线程的ThreadLocalMap中