我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java并发编程之threadLocal

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java并发编程之threadLocal

1、ThreadLocal介绍

多个线程访问同一个共享变量时特别容易出现并发问题,特别是多线程需要对共享变量进行写入时。为了保证线程安全,一般使用者在访问共享变量的时候需要进行适当的同步,如图

同步的一般措施是加锁,这就需要使用者对锁有一定的了解,这显然加重了使用者的负担,那么有没有一种方法可以做到,当创建一个变量后,每个线程对其进行访问的时候访问的是自己线程的变量呢?其实ThreadLocal就可以做到。

ThreadLocalJDK包提供的,它提供了线程本地变量,也就是说如果创建了一个ThreadLocal变量,那么访问这个变量的每一个线程都会有这个变量的一个本地副本。当多线程操作这个变量的时候,实际操作的就是自己本地内存的里面的里面的变量,从而避免了线程安全问题。创建一个ThreadLocal变量后,每一个线程都会复制一个变量到自己的本地内存。

2、ThreadLocal使用实例


package com.heiye.learn1;

public class ThreadLocalTest {
    //print方法
    static void print(String threadName) {
        //打印当前线程本地内存中LocalVariable变量的值
        System.out.println(threadName + ":" + localVariable.get());
        //清除当前线程本地内存中的localVariable变量值
        //localVariable.remove();
    }

    //创建ThreadLocal变量
    static ThreadLocal<String> localVariable = new ThreadLocal<>();

    public static void main(String[] args) {
        //创建线程threadOne
        Thread threadOne = new Thread(new Runnable() {
            @Override
            public void run() {
                //设置线程one变量localVariable值
                localVariable.set("threadOne local Variable");
                //调用打印函数
                print("threadOne");
                //打印本地变量值
                System.out.println("threadOne remove after" + ":" + localVariable.get());
            }
        });
        //创建线程threadTwo
        Thread threadTwo = new Thread(new Runnable() {
            @Override
            public void run() {
                //设置线程two变量localVariable值
                localVariable.set("threadTwo local Variable");
                //调用打印函数
                print("threadTwo");
                //打印本地变量值
                System.out.println("threadTwo remove after" + ":" + localVariable.get());
            }
        });

        threadOne.start();
        threadTwo.start();
    }
}

线程one首先通过set()方法为threadLocal变量设置了一个值,这其实设置的就是线程one本地内存中对于threadLocal变量的一个副本。这个副本是线程two访问不了的。

如果清除当前线程本地内存中的localVariable变量值,也就是执行localVariable.remove() ;则:

3、ThreadLocal实现原理

首先查看一下ThreadLocal类图结构

由该图可知,Thread类有一个ThreadLocalsinheritableThreadLocals,它们都是ThreadLocalMap类型的变量,而ThreadLocalMap是一个定制化的HashMap。在默认的情况下,每个线程中的两个变量都为null,只有当第一个线程调用ThreadLocal的set或者get方法时才会创建它们,其实每个线程得到本地变量不是存放在ThreadLocal实例里面,而是存放在具体的线程内存空间里。ThreadLocal就是一个工具壳,它通过set方法把value值存放在调用线程的threadlocals里面并存放起来,当调用线程调用它的get()方法的时候,再从当前线程的threadLocals变量里面将其拿出来使用。

分析setgetremove逻辑


 //set
 public void set(T value) {
        //获取当前线程
        Thread t = Thread.currentThread();
        //将当前线程作为key,到ThreadLocalMap取查找对应的线程变量
        ThreadLocalMap map = getMap(t);
        //如果找到,则设置
        if (map != null)
            map.set(this, value);
        else //第一次调用就创建当前线程所在的hashmap
            createMap(t, value);
    }

 //get
 public T get() {
        Thread t = Thread.currentThread();
        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();
    }

 //remove
 public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }

在每一个线程内都有一个名为threadLocals的成员变量,该变量的类型为HashMap,其中的key为我们定义的threadLocal变量的this引用,value为我们使用set方法设置的值。每个线程的本地变量存放在自己的内存变量ThreadLocals中,如果当前线程一直不消亡,那么这些本地变量会一直存在,所有可能造成内存溢出。

到此这篇关于Java并发编程 threadLocal 的文章就介绍到这了,更多相关threadLocal 内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java并发编程之threadLocal

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

深入理解Java并发编程之ThreadLocal

本文主要介绍了Java并发编程之ThreadLocal,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2022-11-13

并发编程之ThreadLocal深入理解

在日常的开发中,我们经常会遇到在当前运行线程中保存一些信息,并且各线程之间是隔离的,不会相互影响,不存在并发问题,通过这样的方式来实现请求调用链中方法之间参数传递的解耦,提升代码结构的稳定性等。Java ThreadLocal就是用于实现这

搞懂Java并发—ThreadLocal

ThreadLocal是通过线程隔离的方式防止任务在共享资源上产生冲突, 线程本地存储是一种自动化机制,可以为使用相同变量的每个不同线程都创建不同的存储。

Java 并发 - ThreadLocal详解

ThreadLocal是通过线程隔离的方式防止任务在共享资源上产生冲突, 线程本地存储是一种自动化机制,可以为使用相同变量的每个不同线程都创建不同的存储。 @pdaiJava 并发 - ThreadLocal详解带着BAT大厂的面试问题去理
2022-12-02

理解Java多线程之并发编程

这篇文章主要介绍了理解Java多线程之并发编程的相关资料,需要的朋友可以参考下
2023-02-02

Java高并发编程基础之AQS

大多数人应该都可以说出 CountDownLatch、CyclicBarrier、Sempahore多线程并发三大利器。这三大利器都是通过AbstractQueuedSynchronizer抽象类(下面简写AQS)来实现的,所以学习三大利器

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录