当前位置: 首页 > news >正文

StopWatch与ThreadLocal

目录

1、StopWatch

1、1作用:

1、2方法:

1、3使用方法

 2、ThreadLocal

2、1什么是ThreadLocal

2、2简单例子

2、3使用ThreadLocal带来的四个好处

2、4主要方法

2、5ThreadLocal内存泄漏问题


1、StopWatch

1、1作用:

 统计代码块耗时时间

1、2方法:

  • 构造器:可以使用无参数构造器,也可使用传入一个String类型的id,创建一个指定了id的StopWatch
  • start():可以不传入参数,开始一个无名称的任务的计时,也可以传入String类型的参数来开始指定任务名的任务计时
  • stop():停止当前任务的计时
  • isRunning():返回此stopWatch是否正在计时某任务
  • getTotalTimeMillis():返回所有任务的总体执行时间(毫秒单位)
  • getLastTaskTimeMillis():返回上一个任务的耗时(毫秒单位)
  • prettyPrint():优美地打印所有任务的详细耗时情况

1、3使用方法

引入依赖,Spring框架自带,可不引入

<!-- spring核心包 -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version>
</dependency>
public class StopWatchTest {// 用于模拟一些操作private static void doSomeThing() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {StopWatch stopWatch = new StopWatch();stopWatch.start("任务一");doSomeThing();stopWatch.stop();stopWatch.start("任务二");doSomeThing();stopWatch.stop();System.out.println("stopWatch.isRunning() = " + stopWatch.isRunning());System.out.println(stopWatch.prettyPrint());System.out.println("stopWatch.getTotalTimeMillis() = " + stopWatch.getTotalTimeMillis());System.out.println("stopWatch.getLastTaskTimeMillis() = " + stopWatch.getLastTaskTimeMillis());}}

 2、ThreadLocal

2、1什么是ThreadLocal

ThreadLocal 叫做本地线程变量,ThreadLocal 中填充的的是当前线程的变量,该变量对其他线程而言是封闭且隔离的,ThreadLocal 为变量在每个线程中创建了一个副本,这样每个线程都可以访问自己内部的副本变量.

同一个ThreadLocal所包含的对象,在不同的Threa中有不同的副本,这里有几点需要注意:

  • 因为每个Thread内有自己的实例副本,且该副本只能由当前Thread使用,这也是ThreadLocal命名的由来。
  • 既然每个Thread都有自己的实例副本,且其他Thread不可访问,那就不存在多线程共享的问题

ThreadLocal提供了线程本地的实例,它与普通变量的区别在于:

  • 每个使用该变量的线程都会初始化一个完全独立的实例副本。
  • ThreadLocal变量通常被private static修饰。
  • 当一个线程结束时,它所使用的所有ThreadLocal相对的实例副本都可被回收。

ThreadLocal适用于每个线程需要自己独立的实例,且该实例需要在多个方法中被使用。即变量在线程间隔离,但是在方法和类间共享。

每个Thread对象都有一个ThreadLocalMap,每个ThreadLocalMap可以存储多个ThreadLocal

2、2简单例子

如果没有ThreadLocal,定义一个全局变量后,所有线程都更改的是同一个值

public class TestThread1 {//线程本地存储变量public static int n =0;public static void main(String[] args) {for (int i = 0; i < 3; i++) {//启动三个线程Thread t = new Thread() {@Overridepublic void run() {add10ByThreadLocal();}};t.start();}}/*** 线程本地存储变量加 5*/private static void add10ByThreadLocal() {for (int i = 0; i < 5; i++) {n += 1;System.out.println(Thread.currentThread().getName() + " n=" + n);}}
}

最终 值为15,还可能出现线程安全问题

package com.ljx.splearn;public class TestThreadLocal {//线程本地存储变量private static final ThreadLocal<Integer> THREAD_LOCAL_NUM = new ThreadLocal<Integer>() {@Overrideprotected Integer initialValue() {return 0;}};public static void main(String[] args) {for (int i = 0; i < 3; i++) {//启动三个线程Thread t = new Thread() {@Overridepublic void run() {add10ByThreadLocal();}};t.start();}}/*** 线程本地存储变量加 5*/private static void add10ByThreadLocal() {for (int i = 0; i < 5; i++) {Integer n = THREAD_LOCAL_NUM.get();n += 1;THREAD_LOCAL_NUM.set(n);System.out.println(Thread.currentThread().getName() + " : ThreadLocal num=" + n);}}}

 

打印结果:启动了 3 个线程,每个线程最后都打印到 "ThreadLocal num=5",而不是 num 一直在累加直到值等于 15

经典的使用场景是为每个线程分配一个 JDBC 连接 Connection。这样就可以保证每个线程的都在各自的 Connection 上进行数据库的操作,不会出现 A 线程关了 B线程正在使用的 Connection; 还有 Session 管理 等问题。

还有比如一个请求中需要访问三个服务,三个服务需要在子线程中依次修改用户信息,通常从session中取到用户信息,然后给三个线程操作,这样会出现线程安全问题,需要用锁来保证

使用ThreadLocal后,每个线程都是独立的,互不影响

2、3使用ThreadLocal带来的四个好处

  • 不需要加锁,提高执行效率
  • 线程安全
  • 更高效地利用内存节省开销,上面例子中,相比于成千上万个任务,每个任务都新建一个SimpleDateFormat,显然用ThreadLocal可以节省内存和开销。
  • 免去传参的繁琐,不需要每次都传同样的参数,ThreadLocal使得代码耦合度更低,更优雅

2、4主要方法

  • initialValue()方法会返回当前线程对应的初始值,这是一个延迟加载的方法,只有在调用get()方法的时候才会触发。
  • 如果不重写initialValue()方法,这个方法会返回null,一般使用匿名内部类的方法重写initialValue()方法,以便在后续的使用中可以初始化副本对象。
  • 当线程第一次调用get()方法访问变量的时候,会调用initialValue()方法,除非线程先前调用了set()方法,在这种情况下,不会为线程调用本initialValue()
  • 通常,每个线程最多调用一次initialValue()方法,但如果已经调用一次remove()方法后,再调用get()方法,则可以再次调用initialValue(),相当于第一次调用get()

ThreadLocalMap 类是每个线程Thread类里面的变量,但ThreadLocalMap这个静态内部类定义在ThreadLocal类中

2、5ThreadLocal内存泄漏问题

ThreadLocalMap中的每个Entry都是一个对key弱引用,同时,每个 Entry 都包含了一个对value的强引用

正常情况下,当线程终止时,保存在ThreadLocalMap中的value也会被垃圾回收,因为没有任何强引用了,但是在项目中我们一般使用线程池,线程都是复用的,一般线程都不会结束,那么key对应的value就不会被回收

使用结束后及时调用remove()方法,删除对应的Entry对象,可以避免内存泄漏,所以使用完ThreadLocal之后,应该调用remove()方法。

可同步参考 ThreadLocal详解

相关文章:

StopWatch与ThreadLocal

目录 1、StopWatch 1、1作用&#xff1a; 1、2方法&#xff1a; 1、3使用方法 2、ThreadLocal 2、1什么是ThreadLocal 2、2简单例子 2、3使用ThreadLocal带来的四个好处 2、4主要方法 2、5ThreadLocal内存泄漏问题 1、StopWatch 1、1作用&#xff1a; 统计代码块耗时时…...

20. 有效的括号

给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相同类型的左括…...

微信小程序原生写法传递参数

微信小程序原生写法传递参数 data-xxx 自定义参数名 &#xff0c;接收参数&#xff1a;方法&#xff08;变量名&#xff09; checkVip:function(event) {let that thisconsole.log(event,event)console.log(event.currentTarget.dataset.idx,index)let index Number(eve…...

JavaWeb+jsp+Tomcat的教务查询系统

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88134601?spm1001.2014.3001.5503 jsp/tomcat7.05/MySQL5.7或8版本/ssm框架/spring/ Web框架&#xff1a;SpringBoot/ORM框架&#xff1a;Mybatis/安全框架&#xff1a;Shiro/分页插件&am…...

C# FTP下载 采用Ssh.Net方式

不要再用FTPClient了 nuget下载Ssh.Net 然后代码如下&#xff1a; /// <summary>/// SFTP操作类/// </summary>public class SFTPHelper{#region 字段或属性private SftpClient sftp;/// <summary>/// SFTP连接状态/// </summary>public bool Conne…...

【C++】做一个飞机空战小游戏(三)——模块化程序设计

[导读]本系列博文内容链接如下&#xff1a; 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——模块化程设设计 在前两讲当中&#xff0c;介绍了利用…...

Django使用WebSocket

1、websocket 相关 实现一个系统&#xff0c;20 个用户同时打开网站&#xff0c;呈现出来一个群聊界面 解决方案 轮询&#xff1a;让浏览器每隔2s向后台发送一次请求&#xff0c;缺点&#xff1a;延迟&#xff0c;请求太多网站压力大 长轮询&#xff1a;客户端向服务端发送请…...

看完这篇 教你玩转渗透测试靶机Vulnhub——HarryPotter:Nagini

Vulnhub靶机HarryPotter:Nagini渗透测试详解 Vulnhub靶机介绍&#xff1a;Vulnhub靶机下载&#xff1a;Vulnhub靶机安装&#xff1a;Vulnhub靶机漏洞详解&#xff1a;①&#xff1a;信息收集&#xff1a;②&#xff1a;漏洞发现&#xff1a;③&#xff1a;SSRF漏洞利用&#xf…...

IPO要收紧?业内人士未予以完全确认

“IPO全面收紧、吃穿住等行业标的基本劝退&#xff08;除非行业龙头&#xff09;、科创板第五套标准暂停受理……”在上周末&#xff0c;一篇关于IPO收紧的“小作文”在投行圈内疯狂转发。 距离全面注册制正式实施已过去了5个半月&#xff0c;IPO节奏是否在发生较大变化&#…...

stable difussion Pytorch实现与测试

引言: Stable Diffusion是目前最火的AI绘画工具之一,它是一个免费开源的项目,可以被任何人免费部署和使用。通过Stable Diffusion,可以很轻松的通过文字描述,生成对应的图片。由于它是一个开源项目,开源社区(如:GitHub)中有很多插件和训练好的模型,我们可以直接使用。…...

Redis简述

Redis是什么Redis数据类型Redis应用场景缓存计数器分布式会话排行榜最新列表分布式锁消息队列 Redis出现的问题穿透击穿雪崩 Redis为什么速度快 Redis是什么 redis是一种高速缓存数据库 Redis数据类型 string hash list set zset Redis应用场景 缓存 Redis作为缓存层&…...

Redis 操作List

【分布式】Redis 分布式之List_redissonclient.getlist_比嗨皮兔的博客-CSDN博客 说明 配置文件参考&#xff1a;https://blog.csdn.net/qq_38428623/article/details/123217001?utm_sourceapp&app_version5.1.1&codeapp_1562916241&uLinkIdusr1mkqgl919blen ——…...

多个List 合并变成一个List+一个List 根据某个字段相等的另一个字段相加,并排序变成新的List

List<CurveTimeAndValueDomain> curves new ArrayList<>();for (int i 0; i < columnNames.size(); i){if (columnNames.get(i).equals(PlantConstant.TENDOWNFX) || columnNames.get(i).equals(PlantConstant.TENDOWNQP)) {//10千伏以下 数据 进行缓慢处理cu…...

华为流程体系:流程架构「OES方法」

目录 内容简介 OES方法 端到端的流程 专栏列表 CSDN学院 作者简介 内容简介 今天继续来谈谈华为流程体系中的流程架构。 在前期的内容已经介绍过 POS 流程架构的方法。 这里就先回顾一下 POS 方法的相关内容&#xff1a; 关于 POS&#xff0c;大家可以参看上面的这张图…...

c# 创建一个未定义类的临时对象列表

使用场景&#xff1a;要使用的数据太多&#xff0c;列表/字典无法满足需求&#xff0c;需要传入对象&#xff0c;但是又不想创建模型 new[] 是一种用于创建匿名类型数组的写法。它是 C# 中的一种语法糖&#xff0c;用于简化数组的初始化过程。 在下面代码示例中&#xff0c;ne…...

el-button增加下载功能

vue3和element-plus <el-uploadv-model:file-list"fileList"action"/api/upload"multiple:limit"1":headers"headers" ><el-button type"primary">选择文件</el-button><template #file"{ file …...

prometheus和cAdvisor组合

文章目录 docker内部署PromethuesPrometheuscAdvisorPrometheus和cAdvisor关系配置 docker内部署Promethues Prometheus Prometheus是一个开源的系统监控和报警工具&#xff0c;由SoundCloud开发并在2012年捐赠给了Cloud Native Computing Foundation (CNCF)。它被广泛用于监…...

计算机网络(2) --- 网络套接字UDP

计算机网络&#xff08;1&#xff09; --- 网络介绍_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/131967378?spm1001.2014.3001.5501 目录 1.端口号 2.TCP与UDP协议 1.TCP协议介绍 1.TCP协议 2.UDP协议 3.理解 2.网络字节序 发送逻辑…...

Idea 结合docker-compose 发布项目

Idea 结合docker-compose 发布项目 这里写目录标题 Idea 结合docker-compose 发布项目Docker 开启远程访问功能 添加相应端口配置IDEA 链接Docker配置项目 docker-compose.yml本地还需要安装 dockerwin11 安装本地Docker 可能存在问题 Linux内核不是最新 Docker 开启远程访问功…...

django

django学习 初识Django1.安装django2.创建项目2.1 在终端2.2 Pycharm 3. 创建app4.快速上手4.1 再写一个页面4.2 templates模板4.3 静态文件4.3.1 static目录4.3.2 引用静态文件 5.模板语法案例&#xff1a;伪联通新闻中心6.请求和响应案例&#xff1a;用户登录7.数据库操作7.1…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...