java面试之ThreadLocal问题

这篇具有很好参考价值的文章主要介绍了java面试之ThreadLocal问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是ThreadLocal,它的基本用法是什么 

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

简单来说就是能在多线程中保持变量独立的线程对象

不用Threadlocal多线程访问同一个变量会出现的问题

package com.pxx;

/**
 * Created by Administrator on 2023/9/3.
 */
public class Demo1 {
    private String v1;

    public String getV1() {
        return v1;
    }

    public void setV1(String v1) {
        this.v1 = v1;
    }

    public static void main(String[] args) {
        //开启一个多线程去设置并且访问这个变量

        Demo1 d1 = new Demo1();
        //这里会循环五个线程
        for(int i = 0;i < 5;i++) {
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    //设置并且打印一个变量的数据
                    d1.setV1("data:" + Thread.currentThread().getName());
                    System.out.println("-------------");
                    //取出这个线程对应的名字和值
                    System.out.println(Thread.currentThread().getName() + "=>" + d1.getV1());
                }
            });

            //设置一下每一个线程的名字
            t1.setName("线程" + i);
            t1.start();//开启直接进入到运行状态,然后当前线程开始运行,然后进行下一次循环,下一个线程进来,这个时候进程可能会仙湖干扰
        }

    }
}

下面直接已经线程混乱 

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

 一般来说我们可以用锁来解决,比如引入synchronized,这里我们先不用锁,我们用ThreadLocal这个类去解决

ThreadLocal类去解决线程不同步的问题

它的目的是保持变量独立

下面我们去看一下常见的方法

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

set():将变量绑定到当前线程中

get():获取当前线程绑定的变量

修改一下上面的代码

package com.pxx;

/**
 * Created by Administrator on 2023/9/3.
 */
public class Demo1 {
    //引入绑定变量的线程对象
    ThreadLocal<String>  tl1= new ThreadLocal();

    private String v1;

    public String getV1() {
       // return v1;
        return tl1.get();//得到通过set绑定的变量
    }

    public void setV1(String v1) {
        //this.v1 = v1;
        tl1.set(v1);//直接把这个v1绑定到对象里面
    }

    public static void main(String[] args) {

        Demo1 d1 = new Demo1();
        //这里会循环五个线程
        for(int i = 0;i < 5;i++) {
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    //设置并且打印一个变量的数据
                    d1.setV1("data:" + Thread.currentThread().getName());
                    System.out.println("-------------");
                    //取出这个线程对应的名字和值
                    System.out.println(Thread.currentThread().getName() + "=>" + d1.getV1());
                }
            });

            //设置一下每一个线程的名字
            t1.setName("线程" + i);
            t1.start();//开启直接进入到运行状态,然后当前线程开始运行,然后进行下一次循环,下一个线程进来,这个时候进程可能会仙湖干扰
        }
    }
}

运行结果:

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

 ThreadLocal与synchronized的区别

先把上面的代码变成synchronized给锁住

package com.pxx;

/**
 * Created by Administrator on 2023/9/3.
 */
public class Demo3 {
    //引入绑定变量的线程对象
    ThreadLocal<String>  tl1 = new ThreadLocal();

    private String v1;

    public String getV1() {
        return v1;
    }

    public void setV1(String v1) {
        this.v1 = v1;
    }

    public static void main(String[] args) {

        Demo3 d1 = new Demo3();
        //这里会循环五个线程
        for(int i = 0;i < 5;i++) {
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (d1) {//这个加锁了
                        //设置并且打印一个变量的数据
                        d1.setV1("data:" + Thread.currentThread().getName());
                        System.out.println("-------------");
                        //取出这个线程对应的名字和值
                        System.out.println(Thread.currentThread().getName() + "=>" + d1.getV1());
                    }
                }
            });

            //设置一下每一个线程的名字
            t1.setName("线程" + i);
            t1.start();//开启直接进入到运行状态,然后当前线程开始运行,然后进行下一次循环,下一个线程进来,这个时候进程可能会仙湖干扰
        }
    }

}

运行结果:

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

很明显是锁住了

先来说一下两者的共同点:都是处理多线程并发访问变量的问题

synchronized:它的效率会低一点,因为相当于就是说,线程是排队进行访问的,就像一个教室只有一个厕所,大家都要进去上,就要排队

ThreadLocal:效率高,相当于线程可以同时并发访问,效率高,就像一个教室多个厕所,彼此上,但是相互独立

ThreadLocal的内部结构

最早的一个设计原理

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言 JDK8的设计原理

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

关注一下JDK8,它是把Thread每一个线程作为了一个主线,然后Entry里面存放的是 ThreadLocal这样一个线程对象

这样的设计方案有两个好处:

1.每个map存储的entry变少,因为就是怎么说,Thread线程肯定比ThreadLocal这样一个线程多

2.那么主线Thread销毁掉,里面的map数据对象也就被销毁了

我分析一下源码

先去看set方法

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

再去看一下ThreadLocalMap这个类 

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言 java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

set就是添加到了这个map对象里面

这样不就说明一个问题:解决了线程并发访问,变量出错的问题

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

相当是什么,自己去上自己的厕所,彼此之间相互独立不影响

 可能会造成的一个内存泄漏的问题

他分为两种情况来看:

第一种: 内存不够了,只有溢出memory overflow

第二种:内存泄漏memory leak,在堆上的空间得不到释放,会造成浪费,影响了程序的运行速度,这种浪费多了,就会造成内存的溢出 

我们这里再来引入两个概念

第一个:什么是强引用?我们正常的引用一个对象,没有指向的时候,就会被gc掉,也就是垃圾回收器给回收掉

第二个:什么是弱引用?一句来说,遇到gc就会被回收。只要垃圾回收机制一运行,不管jvm的内存空间时候是否足够,都会回收该对象占用的内存

下面用一张图展示一下引用关系

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

假如是key是强引用的情况

假设ThreadLocal用完了,引用被收回,又因为Map里面的ThreadLocal是一个强引用,所以ThreadLocal对象无法被回收掉

在没手动remove掉Entry类以及CurrentThread依然运行的情况下,Entry类根本不会被挥挥手,会造成内存泄漏

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

假设key是弱引用的情况下,ThreadLocal引用没了,map 里面是一个弱引用指向ThreadLocal,那么就表明ThreadLocal会马上被垃圾回收器给回收掉,他一回收掉,Key就为NULL,那么我们就再也无法访问到value ,value无法被回收,会导致内存泄漏

java面试之ThreadLocal问题,java基础面试题,java,面试,开发语言

很明显源代码给出的是一个弱引用

上面也说明了强引用还是弱引用都会造成内存泄漏

那么造成内存泄漏的根本原因就是:

第一点:Entry类始终存在内存中,没有手动remove

第二点:CurrentThread线程依然在运行

好了,祝你早安午安晚安。文章来源地址https://www.toymoban.com/news/detail-696576.html

到了这里,关于java面试之ThreadLocal问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java安全 URLDNS链分析,网络安全开发面试基础

    this代表的是当前对象的指针,也可以用 this.name 的方式调用当前对象中的成员 那我们去 URLStreamHandler类 当中,查看下 hashCode方法 的代码 protected int hashCode(URL u) { int h = 0; // Generate the protocol part. String protocol = u.getProtocol(); if (protocol != null) h += protocol.hashCode(); // Generate the host pa

    2024年04月23日
    浏览(37)
  • 《面试1v1》ThreadLocal

    我是 javapub,一名 Markdown 程序员从👨‍💻,八股文种子选手。 面试官 : 你好,请问你对 ThreadLocal 有了解吗? 候选人: 您好,我知道 ThreadLocal 是一个 Java 中的类,它可以让每个线程都拥有自己的变量副本,从而避免了线程安全问题。 面试官 : 非常好,那你能否详细介绍

    2024年02月06日
    浏览(50)
  • 面试再也不怕问ThreadLocal了

    要解决多线程并发问题,常见的手段无非就几种。加锁,如使用synchronized,ReentrantLock,加锁可以限制资源只能被一个线程访问;CAS机制,如AtomicInterger,AtomicBoolean等原子类,通过自旋的方式来尝试修改资源;还有本次我们要介绍的ThreadLocal类,通过为每个线程维护一个变量副本

    2024年02月14日
    浏览(38)
  • 2023届计算机保研面试基础专业问题(数据结构、算法、计算机语言、计算机网络、数据库、操作系统、数学)

    以下的专业相关基础问题,是在2022年暑期准备面试过程中,断断续续准备的,最终上岸厦大啦,也希望这些内容对后面准备保研的学弟学妹们有帮助。少即是多、快即是慢,希望大家也不必太焦虑,慢慢来比较快! 堆、栈、队列、链表等数据结构 树:红黑树、二叉树的各类

    2024年02月15日
    浏览(63)
  • 人工智能领域:面试常见问题超全(深度学习基础、卷积模型、对抗神经网络、预训练模型、计算机视觉、自然语言处理、推荐系统、模型压缩、强化学习、元学习)

    【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍:【深度学习入门到进阶】必看系列,含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、

    2024年02月15日
    浏览(70)
  • 《吊打面试官系列》从源码全面解析 ThreadLocal 关键字的来龙去脉

    👏作者简介:大家好,我是爱敲代码的小黄,独角兽企业的Java开发工程师,CSDN博客专家,阿里云专家博主 📕系列专栏:Java设计模式、数据结构和算法、Kafka从入门到成神、Kafka从成神到升仙、Spring从成神到升仙系列 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一

    2023年04月23日
    浏览(67)
  • 【JUC基础】14. ThreadLocal

    目录 1、前言 2、什么是ThreadLocal 3、ThreadLocal作用 4、ThradLocal基本使用 4.1、创建和初始化 4.2、存储和获取线程变量 4.3、清理和释放线程变量 4.4、小结 4.5、示例代码 5、ThreadLocal原理 5.1、set() 5.2、get() 5.3、变量清理 5.4、ThreadLocalMap 6、InheritableThreadLocal 一般提到多线程并发总是

    2024年02月07日
    浏览(39)
  • 【2023,学点儿新Java-14】携程面试题:如何看待Java是一门半编译半解释型的语言?| 咨询互联网行业 资深前辈的一些问题 | 附:为什么说ChatGPT的核心算法是...?| GPT-3.5

    前情回顾: 【2023,学点儿新Java-13】阶段练习之Java面试企业真题(阿里巴巴拼多多 等) | 常用的Java命令行操作都有哪些 | 如何解决Java的内存泄漏和内存溢出问题? 【2023,学点儿新Java-12】小结:阶段性复习 | Java学习书籍推荐(小白该读哪类Java书籍?有一定基础后,再去读

    2024年02月09日
    浏览(49)
  • C语言--基础面试真题

    1、局部变量和静态变量的区别 普通局部变量和静态局部变量区别 存储位置: 普通局部变量存储在栈上 静态局部变量存储在静态存储区 生命周期: 当函数执行完毕时,普通局部变量会被销毁 静态局部变量的生命周期则是整个程序运行期间,即使函数调用结束,静态局部变

    2024年04月27日
    浏览(42)
  • ThreadLocal有内存泄漏问题吗

    对于ThreadLocal的原理不了解或者连Java中的引用类型都不了解的可以看一下我的之前的一篇文章Java中的引用和ThreadLocal_鱼跃鹰飞的博客-CSDN博客 我这里也简单总结一下: 1. 每个Thread里都存储着一个成员变量,ThreadLocalMap 2. ThreadLocal本身不存储数据,像是一个工具类,基于ThreadL

    2024年02月14日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包