秋招Java后端开发冲刺——并发篇2(ThreadLocal、Future接口)

本文对ThreadLocal类和Future接口进行了总结概括,包括ThreadLocal类的原理、内存泄露等问题,和Future接口的使用等问题。

一、ThreadLocal

1. 介绍

ThreadLocal(线程局部变量)是Java中的一个类,线程通过维护一个本地变量副本,从而保证对该变量的访问不受其他线程的影响。
2. 实现原理

  • 每个线程中都有一个ThreadLocalMap 类型的threadLocals 变量和 一个 inheritableThreadLocals 变量
  • ThreadLocalMap是ThreadLocal的静态内部类,存储的是以ThreadLocal实例为 key ,Object 对象为 value 的键值对
  • 当调用ThreadLocal类实例的get和set方法修改变量值的时候实际上调用的是ThreadLocalMap类的get和set方法,数据实际存储在ThreadLocalMap中
  • 源码

① get方法

bash 复制代码
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();
}

② set方法

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

ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}

void createMap(Thread t, T firstValue) {
    t.threadLocals = new ThreadLocalMap(this, firstValue);
}

3. 内存泄漏问题

(1)虚引用、弱引用、软引用和强引用

  • 虚引用:主要用于在对象被回收时,进行一些后续处理工作;必须和引用队列(ReferenceQueue)联合使用
  • 弱引用:主要用于实现规范化映射;当垃圾收集器运行时,无论内存是否充足都会回收这些对象
  • 软引用:要用于实现内存敏感的缓存;在垃圾收集器判断内存不足时,会回收这些对象
  • 强引用:当一个对象被强引用时,垃圾收集器不会回收该对象,即使内存不足也不会回收。通过new对象实例可以创建。

(2)ThreaLocal内存泄露是因为ThreadLocalMap 中的 key 为 ThreadLocal 的弱引用 ,而 value 是强引用 ,因此当垃圾回收时会回收ThreadLocal对象实例,而与之对应的value不会被回收,之后该value也不能再使用,由此导致内存泄露。
:使用ThreadLocal时一定要手动调用remove()方法

二、 Future接口

1. 介绍

Future 接口提供了一种处理异步计算结果的机制,通过使用 Future 和 其实现类FutureTask ,可以方便地处理并发编程中的异步任务管理。
2. 常用方法

方法 描述
boolean cancel(boolean mayInterruptIfRunning) 尝试取消任务的执行。如果任务已完成或已被取消,返回 falsemayInterruptIfRunning 指示是否应该中断正在执行的任务。
boolean isCancelled() 如果任务在完成前被取消,则返回 true
boolean isDone() 如果任务已完成(无论是正常完成、异常终止还是取消),返回 true
V get() throws InterruptedException, ExecutionException 等待任务完成并获取结果。如果任务执行过程中抛出异常,则抛出 ExecutionException。若当前线程被中断,抛出 InterruptedException
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException 在指定时间内等待任务完成并获取结果。如果在指定时间内任务没有完成,抛出 TimeoutException。若任务执行过程中抛出异常,抛出 ExecutionException。若当前线程被中断,抛出 InterruptedException

3. CompletableFuture 和Future之间的区别与联系

特性 Future CompletableFuture
接口/类 接口 类(实现了 Future 和 CompletionStage 接口)
异步任务 不能直接表示异步任务,只能表示异步任务的结果 可以直接表示异步任务并提供丰富的异步编程支持
任务完成通知 只能通过阻塞的 get 方法或轮询 isDone 方法检查任务是否完成 提供 thenApply, thenAccept, thenRun 等方法来注册回调函数,在任务完成时自动执行
手动完成 不支持手动完成任务 提供 complete, completeExceptionally 等方法手动完成任务
组合多个任务 不支持直接组合多个任务 提供 allOf, anyOf 等方法来组合多个任务
异常处理 只能通过捕获 ExecutionException 进行异常处理 提供 exceptionally, handle, whenComplete 等方法进行异常处理
非阻塞获取结果 不支持非阻塞地获取结果 提供 join, getNow, orTimeout, completeOnTimeout 等方法非阻塞地获取结果或处理超时
支持流式 API 不支持流式 API 支持流式 API,允许通过链式调用编写更简洁和可读的异步代码
相关推荐
小_太_阳4 分钟前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
向宇it5 分钟前
【从零开始入门unity游戏开发之——unity篇02】unity6基础入门——软件下载安装、Unity Hub配置、安装unity编辑器、许可证管理
开发语言·unity·c#·编辑器·游戏引擎
智慧老师13 分钟前
Spring基础分析13-Spring Security框架
java·后端·spring
lxyzcm15 分钟前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
古希腊掌管学习的神41 分钟前
[LeetCode-Python版]相向双指针——611. 有效三角形的个数
开发语言·python·leetcode
赵钰老师42 分钟前
【R语言遥感技术】“R+遥感”的水环境综合评价方法
开发语言·数据分析·r语言
V+zmm101341 小时前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
就爱学编程1 小时前
重生之我在异世界学编程之C语言小项目:通讯录
c语言·开发语言·数据结构·算法
Oneforlove_twoforjob1 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
emoji1111111 小时前
前端对页面数据进行缓存
开发语言·前端·javascript