并发编程--ThreadLocal

简介: 并发编程--ThreadLocal

@[toc]

1.什么是Threadlocal

ThreadLocal提高一个线程的局部变量,访问某个线程拥有自己局部变量。
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

static final ThreadLocal<T> sThreadLocal = new ThreadLocal<T>();
sThreadLocal.set()
sThreadLocal.get()

threadlocal而是一个线程内部的存储类,可以在指定线程内存储数据,数据存储以后,只有指定线程可以得到存储数据,官方解释如下。

/**

  • 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 associate state with a thread (e.g.,
  • a user ID or Transaction ID).
    */

大致意思就是ThreadLocal提供了线程内存储变量的能力,这些变量不同之处在于每一个线程读取的变量是对应的互相独立的。通过get和set方法就可以得到当前线程对应的值。

做个不恰当的比喻,从表面上看ThreadLocal相当于维护了一个map,key就是当前的线程,value就是需要存储的对象。

案例如下

package com.yxl.demo.ThreadTest;

public class Test6 {

    public static void main(String[] args) {
        Res res=new Res();
        Thread thread = new Thread(res,"6666");
        Thread thread2 = new Thread(res,"777");
        thread.start();
        thread2.start();

    }


}

class Res implements Runnable {
    public  static Integer count = 0;

    public  Integer getNumber(){

        return count++;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3 ; i++) {
            System.out.println(Thread.currentThread().getName()+ ","+getNumber());
        }
    }
}

运行结果 :发现都是共享变量,现在需要让 res 变成局部变量
在这里插入图片描述

需要变成局部变量,解决方案 使用Threadlocal

package com.yxl.demo.ThreadTest;

public class Test6 {

    public static void main(String[] args) {
        Res test6=new Res();
        Thread thread = new Thread(test6,"6666");
        Thread thread2 = new Thread(test6,"777");
        thread.start();
        thread2.start();

    }


}

class Res implements Runnable {
    //public  static Integer count = 0;

    //创建ThreadLocal
    public static ThreadLocal<Integer> threadLocal =new ThreadLocal<Integer>(){
        protected Integer initialValue(){
            return  0;
        }
    };

    public  Integer getNumber(){
        int count = threadLocal.get()+1;
        threadLocal.set(count);
        return count;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3 ; i++) {
            System.out.println(Thread.currentThread().getName()+ ","+getNumber());
        }
    }
}

运行结果:

在这里插入图片描述

ThreadLoca实现原理

ThreadLoca通过map集合
Map.put(“当前线程”,值);

底层 get方法


public T get() {
        //获取线程
        Thread t = Thread.currentThread();
        //其中getMap(t)返回的就上当前线程的threadlocals
        ThreadLocalMap map = getMap(t);
        //判断map是否null
        //然后根据当前ThreadLocal实例对象作为key获取ThreadLocalMap中的value,如果首次进来这调用setInitialValue()
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

底层 set 方法:(同get)

public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

ThreadLocal 应用场景

1.用户登录,从token那用户唯一标识,方到threadLocal里边。在业务层就能随时用了
2.事务控制 ,哪条线程执行哪条sql需要回滚

相关文章
|
4月前
|
存储 Java
JUC并发编程之深入理解ThreadLocal
ThreadLocal是Java标准库提供的一个工具类,位于java.lang包下。它允许你创建一个线程局部变量,每个线程都可以独立地访问自己的变量副本,互不干扰。这在某些场景下非常有用,比如在多线程环境下,每个线程需要维护自己的状态信息,但又不想通过方法参数传递的方式来实现。
|
4月前
|
存储 安全 Java
面试题:用过ThreadLocal吗?ThreadLocal是在哪个包下的?看过ThreadLocal源码吗?讲一下ThreadLocal的get和put是怎么实现的?
字节面试题:用过ThreadLocal吗?ThreadLocal是在哪个包下的?看过ThreadLocal源码吗?讲一下ThreadLocal的get和put是怎么实现的?
60 0
|
存储 算法 安全
【多线程系列-05】深入理解ThreadLocal的底层原理和基本使用
【多线程系列-05】深入理解ThreadLocal的底层原理和基本使用
241 4
|
存储 SpringCloudAlibaba Java
浅析ThreadLocal使用及实现原理
提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其`get` 或 `set`方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。`ThreadLocal`实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联 。所以ThreadLocal与线程同步机制不同,线程同步机制是多个线程共享同一个变量,而ThreadLocal是为每一个线程创建一个单独的变量副本,故而每个线程都可以独立地改变自己所拥有的变量副本,而不会影响其他线程所对应的副本。可以这么说Th
96 0
浅析ThreadLocal使用及实现原理
|
存储 安全 Java
【JUC基础】14. ThreadLocal
一般提到多线程并发总是要说资源竞争,线程安全。而通常保证线程安全的其中一种方式便是控制资源的访问,也就是加锁。其实还有另一种方式,那么便是增加资源来保证所有对象不竞争少数资源。比如,有100个人需要填写信息表,如果只有一只笔,那么要么变成串行,一个一个填写,要么就是我写一半你写一半。那么如果准备100只笔,100个人每个人都有一只笔能够填写信息表,那么就不会出现竞争的情况,也就能顺利的保证信息表的填写。这支笔也就是我们今天要说的ThreadLocal。
|
存储 安全 Java
【并发编程】ThreadLocal详解
【并发编程】ThreadLocal详解
|
缓存 安全 Java
如何使用ThreadLocal避免线程安全问题?
这篇文章是关于ThreadLocal的第二篇文章。 在上一篇文章,Yasin给大家介绍了什么是ThreadLocal,以及ThreadLocal的基本原理。 那在实际工作中,ThreadLocal一般用来做什么呢?今天我们以一个简单的应用场景为例,给大家介绍如何用ThreadLocal来帮助我们解决多线程的安全问题。
392 0
|
Java 关系型数据库 MySQL
Java并发:ThreadLocal详解
Java并发:ThreadLocal详解
232 1
|
存储 缓存 Java
JUC并发编程——ThreadLocal
JUC并发编程——ThreadLocal
134 0
JUC并发编程——ThreadLocal
|
存储 Java
ThreadLocal 实现原理
ThreadLocal 实现原理
138 0
ThreadLocal 实现原理