多线程与高并发编程(五),面试字节跳动Java工程师该怎么准备

  1. 用法

ThreadLocal tl = new ThreadLocal<>() 这里的T是任意对象

t1.get() 从ThreadLocal中取

t1.set(Object) 放入ThreadLocal

注:

ThreadLocal中的值和对象只是针对自己线程的。两个线程对同一个t1对象的读写是隔离的。

  1. 源码实现

①:以set()方法为例(比如T是一个叫Person的类)

内部是有一个Map

ThreadLocal.java:Thread.currentThread()获取了当前线程

在这里插入图片描述

这里的getMap(t)进入,发现获取了一个ThreadLocalMap,这个map是在Thread中:

在这里插入图片描述

总结上面Thread.currentThread.map(ThreadLocal, person)获取了当前线程中的一个map中,所以其实不是一个map用不同Thread做key的隔离,实际上是不同的Thread用不同的map。

这个ThreadLocalMap内可以存在多个key:value,key是ThreadLocal,value是set进来的对象,每个ThreadLocal只能set自己的,那么代表这个map是全局通用的,每个声明的ThreadLocal.set()时,都会对同一个map.put()内容。

  1. ThreadLocal用途

声明式事务,保证同一个connection(例如配置中有四项都是要连接数据库,就可以合并成为一个事务,但是不同的连接之间肯定不能合并为一个事务,那么第一个取的时候把这个connection放入本地线程的ThreadLocal中,以后的连接实际上都是从这个ThreadLocal中来取,保证是同一个链接,这部分知识应该是基础中的)

四、JAVA中的引用

=========================================================================

引用一共四种:强、软、弱、虚

  1. 强引用:

普通的引用就是强引用(Object o = new Object())

垃圾回收时,有引用指向的空间一定不会被回收,也就是强引用不会被垃圾回收,除非下面你Object o = null,然后调用了System.gc(),System.in.read()(这句话是为了阻塞当前线程的,没有特殊含义,因为gc是跑在别的线程中的,这样阻塞一下main的线程,防止main结束,要是main结束了,gc也没啥意义了)

  1. 软引用:

一个对象若只有一个软引用指向他,只有当系统堆内存不够用时才会被回收。

SoftReference。下图中m指向了一个softReference软引用,这个软引用指向了一个字节数组。

在这里插入图片描述

用途:做缓存用,比如说从数据库取了一堆数据,需要用直接存缓存取,空间不够了就可以去掉,平时很难用到。

  1. 弱引用(面试重点):

只要遭遇到gc就会回收

weakReference。下图中m只想了一个weakReference弱引用,这个弱引用指向了M对象,这个声明之后直接system.gc()就null了。

在这里插入图片描述

用途:这个M对象若除了这个弱引用还有个强引用指向它,那么当强引用消失之后,这个对象就应该被回收。

一般用在容器中

在ThreadLocal(基本上下图就是ThreadLocal面试能问到的最深处)中应用(实线是强引用,虚线是弱引用,tl是声明的ThreadLocal对象):

在这里插入图片描述

在这里插入图片描述

ThreadLocal中发现Entry(map中是entry这个key:value)的key实际上是一个弱引用指向ThreadLocal(因为内部的map的key是ThreadLocal),源码如下图(ThreadLocal内):

在这里插入图片描述

若key指向ThreadLocal是强引用,那么tl这个ThreadLocal的声明都不指向这个ThreadLocal时,那么因为ThreadLocal有强引用指向他,所以他永远不会被回收,而有些游戏服务器之类的,可能这个Thread永远不会停,那么这块区域就会永远不被回收,这块就发生了内存泄漏,单这个key若是弱引用的话,tl消失时这个指向的ThreadLocal就被回收了,因为tl都不指向这里了,map指向这个ThreadLocal没意义了所以无影响。

补充知识(内存泄漏:内存中有一块永远不会被回收。 OOM:内存分配不够使了。 完全不同的概念)。

ThreadLocal的坑:

key指向的弱引用,回收之后key变成了null,但是这个map永远存在的,所以这个value还是指向了另外的对象,所以ThreadLocal在每次使用完之后一定要手工tl.remove()回收ThreadLocal,否则这个map越来越大之后还是会在发生内存泄漏,慢慢的OOM了!如下图:

在这里插入图片描述

  1. 虚引用:

主要是处理堆外内存的。

在这里插入图片描述

PhantomReference,声明的条件苛刻,第二个必须是一个队列。

在这里插入图片描述

虚引用被垃圾回收发现直接就会被干掉,被干掉时放入声明时的那个队列中一个值,检测队列中出现了值就代表虚引用被干掉了,往队列中扔一个值就是虚引用被干掉通知的方式。

PhantomReference.get(),无论什么时候都拿不到值(不像上面那几个有引用就能拿到,这里有了也拿不到)。

用途:基本用不上,给写JVM人用的,写netty之类的也可以,一般他们都会监控这个队列,发现被通知之后就会做出一些处理

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频**

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-9IQ4FEZZ-1710923699862)]

  • 10
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值