并发编程--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需要回滚

相关文章
|
存储 安全 Java
【并发编程】ThreadLocal详解
【并发编程】ThreadLocal详解
|
存储 安全 Java
多线程之ThreadLocal理解、应用及源码分析
        一、引入:为什么要使用ThreadLocal         之前,在某位大牛的一篇文章中,看到了实现线程安全的几个层次,分别是:         1、使用无状态的对象               无状态对象也就是不变的对象,它是最安全的,因此不需要考虑线程间同步等安全...
1060 0
|
缓存 安全 Java
如何使用ThreadLocal避免线程安全问题?
这篇文章是关于ThreadLocal的第二篇文章。 在上一篇文章,Yasin给大家介绍了什么是ThreadLocal,以及ThreadLocal的基本原理。 那在实际工作中,ThreadLocal一般用来做什么呢?今天我们以一个简单的应用场景为例,给大家介绍如何用ThreadLocal来帮助我们解决多线程的安全问题。
430 0
|
数据采集 存储 安全
并发编程 ThreadLocal源码分析
引入ThreadLocal的场景 最近在写项目的时候自己也有疑虑,因为这个项目涉及到爬虫,使用的WebMagic这款垂直爬虫框架 垂直式爬虫 垂直型爬虫关注内容与准确还有效率.
1532 0
|
7月前
|
存储 安全 Java
多线程线程安全问题之ThreadLocal是什么,它通常用于什么场景
多线程线程安全问题之ThreadLocal是什么,它通常用于什么场景
|
9月前
|
存储 Java
JUC并发编程之深入理解ThreadLocal
ThreadLocal是Java标准库提供的一个工具类,位于java.lang包下。它允许你创建一个线程局部变量,每个线程都可以独立地访问自己的变量副本,互不干扰。这在某些场景下非常有用,比如在多线程环境下,每个线程需要维护自己的状态信息,但又不想通过方法参数传递的方式来实现。
|
存储 缓存 Java
JUC并发编程——ThreadLocal
JUC并发编程——ThreadLocal
163 0
JUC并发编程——ThreadLocal
|
安全 Java
Java并发编程 -- 单例模式线程安全问题
单例模式是指对一个对象进行一次实例化,然后全局都可以调用该实例化对象来完成项目的开发。 在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。
913 0
|
5月前
|
算法 安全 Java
JAVA并发编程系列(12)ThreadLocal就是这么简单|建议收藏
很多人都以为TreadLocal很难很深奥,尤其被问到ThreadLocal数据结构、以及如何发生的内存泄漏问题,候选人容易谈虎色变。 日常大家用这个的很少,甚至很多近10年资深研发人员,都没有用过ThreadLocal。本文由浅入深、并且才有通俗易懂方式全面分析ThreadLocal的应用场景、数据结构、内存泄漏问题。降低大家学习啃骨头的心理压力,希望可以帮助大家彻底掌握并应用这个核心技术到工作当中。

热门文章

最新文章