首页 > 其他分享 >ThreadLocal实践案例两则

ThreadLocal实践案例两则

时间:2023-08-02 17:35:44浏览次数:45  
标签:return Online 接口 案例 ThreadLocal 线程 两则 static

ThreadLocal是Java中的一个类,全路径:java.lang.ThreadLocal,用于在多线程环境下存储线程本地变量。在多线程应用程序中,不同线程之间共享数据可能会引发线程安全问题。

ThreadLocal通过为每个线程创建独立的变量副本,保证了线程间数据的隔离性,从而有效地解决了这一问题。线程之间的数据访问操作互不影响,提高了多线程应用程序的性能和可靠性。

ThreadLocal通常与线程池、异步任务和Web应用程序等场景结合使用,使得在多线程编程时更加方便和安全。

虽然ThreadLocal有这么多好处,但在之前的实际使用中用的并不多,只有在性能测试中的随机数性能问题探索随机方法性能差异中有所使用。结论分享一下java.util.concurrent.ThreadLocalRandom这个性能最好。

在近期的测试实践中,又发现了一些有趣的应用场景,分享给大家。

场景一

我有一个工具类,用来去平台获取部分信息。伪代码如下:

package com.funtest.temp

import com.funtester.frame.SourceCode

class ThreadLocalTest extends SourceCode{

    /**
     * 获取域名
     * @return
     */
    static String getHost() {
        return EMPTY
    }

    /**
     * 获取信息
     * @return
     */
    static String getMsg() {
        return getHost() + "/funtester"
    }

    /**
     * 获取响应
     * @param url
     * @return
     */
    static String getRes(String url) {
        return EMPTY
    }

}

之所以设计getHost()这个方法原因是因为不同有不止一个地址所以写了这个方法(可忽略)。本来用来跑任务之后1个地址,所以getHost()只需要写死一个返回值即可。但是新需求来了,每次定时任务需要跑两个环境。

首先想到的思路就是在所有getMsg()方法里面都添加一个参数,用来标识请求的是哪个环境,这样做看起来比较简单,但是改动地方太多了。而且基于这些方法的脚本已经有不少一直在跑,一旦改动,发布之后还得重新修改脚本。

如果增加一个全局属性,那么在多个线程都在跑任务(假设会有交叉)的时候,这个全局属性就会被多个线程修改,导致线程不安全的问题。

然后我就想到了ThreadLocal,因为跑任务时候,我都是用线程池去跑,也就是所每个任务都有一个线程。这样我可以针对每个线程设置一个属性。每个线程修改当前线程持有的ThreadLocal属性又不会影响到其他线程。

真是瞌睡递枕头。

	static ThreadLocal<Boolean> Online = new ThreadLocal<Boolean>(){

        @Override
        protected Boolean initialValue() {
            return true
        }
    }
    

这样就可以在执行不同的环境时候,调用Online.set()方法进行修改了。

场景一

这是在Springboot开发过程中遇到的。原因跟以上有点像,但并不是static方法。简单描述一下:A接口参数aBean,B接口参数bBean,A接口实现中使用到了B接口的方法。以此为背景。

某次需求更新,需要在A接口增加一项功能,在对某个参数值扩充(这个值不会传递给bBean),针对新值在调用B接口方法的时候特殊处理。

这个时候我又想到了ThreadLocal,毕竟两件事情没隔几天。索性在A、B接口实现类中增加一个ThreadLocal的成员变量,A接口在获取到参数时,初始化这个变量。这样B接口就可以在处理时,获取变量,进行差别对待了。

虽然这个例子有点牵强,但在实践中确实简单高效的方式。如果改造aBeanbBean,势必会导致B接口出现多余字段(也可称为非必传字段),在我看来有点不能忍。

所以这虽然不是一个常见的解决方案,但在我的这种场景下,确实一个非常nice的方案。成本低,改动小,上线快。

当然也会给后续维护者造成一点点的困惑。这就是另一个故事了。

关于内存泄露

在看资料过程中,很多建议使用者规范使用ThreadLocal类,容易造成内存泄露。大家可以搜一搜看一看,还是很有必要的。

前面两个例子之所以没有使用规范,原因是因为在执行过程中,多次调用了Online.set()Online.get()方法,会帮助JVM回收资源。不用额外调用Online.remove()主动释放内存。

标签:return,Online,接口,案例,ThreadLocal,线程,两则,static
From: https://blog.51cto.com/FunTester/6940493

相关文章

  • Unity的IPostprocessBuildWithReport:深入解析与实用案例
    UnityIPostprocessBuildWithReportUnityIPostprocessBuildWithReport是Unity引擎中的一个非常有用的功能,它可以让开发者在构建项目后自动执行一些操作,并且可以获取构建报告。这个功能可以帮助开发提高工作效率,减少手动操作的时间和错误率。在本文中,我们将介绍UnityIPostproces......
  • 岩土工程安全监测案例分析
    振弦传感器、振弦采集仪和在线监测系统是岩土工程监测中常用的装置。下面是一个典型的振弦传感器和在线监测系统的应用案例:项目简介:该项目是某高速公路隧道的岩土工程监测案例,隧道长度为5.8公里,全线由6个监测截面组成。监测截面每隔200米一个,共设置了30个监测点。监测方案:为确......
  • 服务器数据恢复-raid5更换新磁盘在同步数据过程中又一块磁盘离线导致阵列崩溃的数据恢
    服务器数据恢复环境:某研究院一台DELL存储,15块硬盘搭建的一组RAID5磁盘阵列。该RAID5阵列只有一个卷组,该卷组占用了阵列的全部空间;该卷组只有一个起始位置为0扇区的XFS裸分区。服务器故障&初检&分析:该RAID5阵列中有一块硬盘由于未知原因离线,工作人员更换新硬盘,在RAID阵列进行数......
  • day11 11.2 JNI案例
    【一】创建项目【1】新建utils.c在cpp文件夹下新建utils.c的源文件,后缀名是c,因为怎么用c写(.cpp是c++,不要用这个)【2】新建java类新建一个java类,类中写函数packagecom.dream.demo11;publicclassUtils{//定义一个方法,实现C中的某个方法相对应publi......
  • 案例|会展大数据服务系统 智能服务体系建设实践
    根据相关的市场调查发现在国内进行的2000多个会展项目中,仅有15%的项目能够提供相关主题网站基本业务和服务,且提供的服务并不能够满足会展各方的应用,剩余的大部门会展项目信息系统构建的不够完善、技术性差、应用复杂等,甚至提供的只是静态的图画。随着信息技术的不断发展,展览信息化......
  • 案例分享|从发现到处理,15分钟故障解决
    ......
  • 1案例答题技巧
    分析问题----找出问题要点-----通过定性分析定量估算----构思答案要点-----以简练的语言作答(按条目列出):提炼问题要点-阅读-分析-构思-简练答题注意是记正分(不会倒扣分数):把认为对的都写上顺势而为(上下文)......
  • vue--day50--todolist案例自定义事件修改footer 和header 修改
    1.MyHeader.vue<template><divclass="todo-header"><!--v-model:="title"是实时绑定的--><inputtype="text"placeholder="请输入你的任务名称,回车键确认"v-model="title"@keyup.enter="add"/>......
  • Unity的IPreprocessBuildWithReport:深入解析与实用案例
    UnityIPreprocessBuildWithReportUnityIPreprocessBuildWithReport是Unity引擎中的一个非常有用的功能,它可以让开发者在构建项目时自动执行一些操作,并且可以获取构建报告。这个功能可以帮助开发者提高工作效率,减少手动操作的时间和错误率。在本文中,我们将介绍UnityIPreprocess......
  • 三菱plcCCLINK转profinet与西门子PLC通讯案例分析
    用三菱PLC的控制系统需要和西门子的PLC控制系统交互数据,捷米JM-PN-CCLK 是自主研发的一款 PROFINET 从站功能的通讯网关。该产品主要功能是将各种 CCLINK 总线和 PROFINET 网络连接起来。 捷米JM-PN-CCLK总线中做为从站使用,连接到 CCLINK 总线中做为从站使用。  三......