ThreadLocal,实现安全的多线程

Spring-利用ThreadLocal解决线程安全问题(多线程并发登录) ThreadLocal是什么ThreadLocal,顾名思义,它不是一个线程,而是线程的一个本地化对象。当工作于多线程中的对象使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程分配一个独立的变量副本。所以每一个线程都可以独立地改变自己的副本,而不会影响其他线程所对应的副本。从线程的角度看,这个变量就像是线程的本地变量,这也是类名中“Local”所要表达的意思。Thr... 阅读详情

ThreadLocal,实现安全的多线程

我们知道Spring通过各种DAO模板类降低了开发者使用各种数据持久技术的难度。这些模板类都是线程安全的,也就是说,多个DAO可以复用同一个模板实例而不会发生冲突。

我们使用模板类访问底层数据,根据持久化技术的不同,模板类需要绑定数据连接或会话的资源。但这些资源本身是非线程安全的,也就是说它们不能在同一时刻被多个线程共享。

虽然模板类通过资源池获取数据连接或会话,但资源池本身解决的是数据连接或会话的缓存问题,并非数据连接或会话的线程安全问题。

按照传统经验,如果某个对象是非线程安全的,在多线程环境下,对对象的访问必须采用synchronized进行线程同步。但Spring的DAO模板类并未采用线程同步机制,因为线程同步限制了并发访问,会带来很大的性能损失。

此外,通过代码同步解决性能安全问题挑战性很大,可能会增强好几倍的实现难度。那模板类究竟仰丈何种魔法神功,可以在无需同步的情况下就化解线程安全的难题呢?答案就是ThreadLocal!

ThreadLocal在Spring中发挥着重要的作用,在管理request作用域的Bean、事务管理、任务调度、AOP等模块都出现了它们的身影,起着举足轻重的作用。要想了解Spring事务管理的底层技术,ThreadLocal是必须攻克的山头堡垒。

ThreadLocal是什么

早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。

ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些。

当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。

线程局部变量并不是Java的新发明,很多语言(如IBM IBM XL FORTRAN)在语法层面就提供线程局部变量。在Java中没有提供在语言级支持,而是变相地通过ThreadLocal的类提供支持。

所以,在Java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在Java开发者中得到很好的普及。

ThreadLocal的接口方法

ThreadLocal类接口很简单,只有4个方法,我们先来了解一下:

void set(Object value)

设置当前线程的线程局部变量的值。

public Object get()

该方法返回当前线程所对应的线程局部变量。

public void remove()

将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。

protected Object initialValue()

返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal<T>。API方法也相应进行了调整,新版本的API方法分别是void set(T value)、T get()以及T initialValue()。

ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单:在ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本。我们自己就可以提供一个简单的实现版本:

// 代码清单1 SimpleThreadLocal

class SimpleThreadLocal {

private Map valueMap = Collections.synchronizedMap(new HashMap());

public void set(Object newValue) {

valueMap.put(Thread.currentThread(), newValue);// ①键为线程对象,值为本线程的变量副本

}

public Object get() {

Thread currentThread = Thread.currentThread();

Object o = valueMap.get(currentThread);// ②返回本线程对应的变量

if (o == null && !valueMap.containsKey(currentThread)) {// ③如果在Map中不存在,放到Map

// 中保存起来。

o = initialValue();

valueMap.put(currentThread, o);

}

return o;

}

public void remove() {

valueMap.remove(Thread.currentThread());

}

public Object initialValue() {

return null;

}

}

虽然代码清单9?3这个ThreadLocal实现版本显得比较幼稚,但它和JDK所提供的ThreadLocal类在实现思路上是相近的。

一个TheadLocal实例

下面,我们通过一个具体的实例了解一下ThreadLocal的具体使用方法

package threadLocalDemo;

public class SequenceNumber {

// ①通过匿名内部类覆盖ThreadLocal的initialValue()方法,指定初始值

private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {

public Integer initialValue() {

return 0;

}

};

// ②获取下一个序列值

public int getNextNum() {

seqNum.set(seqNum.get() + 1);

return seqNum.get();

}

public static void main(String[] args)

{

SequenceNumber sn = new SequenceNumber();

// ③ 3个线程共享sn,各自产生序列号

TestClient t1 = new TestClient(sn);

TestClient t2 = new TestClient(sn);

TestClient t3 = new TestClient(sn);

t1.start();

t2.start();

t3.start();

}

private static class TestClient extends Thread

{

private SequenceNumber sn;

public TestClient(SequenceNumber sn) {

this.sn = sn;

}

public void run()

{

for (int i = 0; i < 3; i++) {

// ④每个线程打出3个序列值

System.out.println("thread[" + Thread.currentThread().getName()+"] sn[" + sn.getNextNum() + "]");

}

}

}

}

通常我们通过匿名内部类的方式定义ThreadLocal的子类,提供初始的变量值,如例子中①处所示。TestClient线程产生一组序列号,在③处,我们生成3个TestClient,它们共享同一个SequenceNumber实例。运行以上代码,在控制台上输出以下的结果:

thread[Thread-2] sn[1]

thread[Thread-0] sn[1]

thread[Thread-1] sn[1]

thread[Thread-2] sn[2]

thread[Thread-0] sn[2]

thread[Thread-1] sn[2]

thread[Thread-2] sn[3]

thread[Thread-0] sn[3]

thread[Thread-1] sn[3]

考察输出的结果信息,我们发现每个线程所产生的序号虽然都共享同一个SequenceNumber实例,但它们并没有发生相互干扰的情况,而是各自产生独立的序列号,这是因为我们通过ThreadLocal为每一个线程提供了单独的副本。

Thread同步机制的比较

ThreadLocal和线程同步机制相比有什么优势呢?ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。

在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。

而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

由于ThreadLocal中可以持有任何类型的对象,低版本JDK所提供的get()返回的是Object对象,需要强制类型转换。但JDK 5.0通过泛型很好的解决了这个问题,在一定程度地简化ThreadLocal的使用,代码清单 9 2就使用了JDK 5.0新的ThreadLocal<T>版本。

概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。

Spring使用ThreadLocal解决线程安全问题

我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、 TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用 ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。

一般的Web应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用。在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程,如图9?2所示:

图1同一线程贯通三层

这样你就可以根据需要,将一些非线程安全的变量以ThreadLocal存放,在同一次请求响应的调用线程中,所有关联的对象引用到的都是同一个变量。

下面的实例能够体现Spring对有状态Bean的改造思路:

代码清单3 TopicDao:非线程安全

public class TopicDao {

private Connection conn;①一个非线程安全的变量

public void addTopic(){

Statement stat = conn.createStatement();②引用非线程安全变量

…

}

}

由于①处的conn是成员变量,因为addTopic()方法是非线程安全的,必须在使用时创建一个新TopicDao实例(非singleton)。下面使用ThreadLocal对conn这个非线程安全的“状态”进行改造:

代码清单4 TopicDao:线程安全

package threadLocalDemo;

import java.sql.Connection;

import java.sql.SQLException;

import java.sql.Statement;

public class SqlConnection {

// ①使用ThreadLocal保存Connection变量

private static ThreadLocal<Connection> connThreadLocal = new ThreadLocal<Connection>();

public static Connection getConnection() {

// ②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection,

// 并将其保存到线程本地变量中。

if (connThreadLocal.get() == null) {

Connection conn = getConnection();

connThreadLocal.set(conn);

return conn;

} else {

return connThreadLocal.get();

// ③直接返回线程本地变量

}

}

public void addTopic() {

// ④从ThreadLocal中获取线程对应的Connection

try {

Statement stat = getConnection().createStatement();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

手把手教你学 Simulink (1.3)--Simulink 的模块库及其模块介绍 Simulink 提供了丰富的模块库,涵盖了从基本的信号生成和处理到复杂的数学运算和系统建模的各种功能。通过熟悉这些模块库及其模块,你可以更高效地构建和仿真动态系统。 阅读详情

相关推荐

从Applied Intelligence被拒到The Visual Computer录用:我的计算机视觉论文投稿时间线全记录(含详细修改意见)

本文详细记录了作者从Applied Intelligence被拒到The Visual Computer成功发表计算机视觉论文的全过程,重点分享了如何将模糊的拒稿理由转化为具体改进方案。文章包含技术改进细节、写作调整策略以及期刊选择经验,为计算机视觉领域的研究者提供了实用的投稿指南。

weixin_30872499的博客 464

解决多线程间共享变量线程安全问题的大杀器——ThreadLocal

上一期,讲到了关于线程死锁、用户进程、用户线程的相关知识,不记得的小伙伴可以看看:字节跳动面试官问我:你知道线程死锁吗?用户线程、守护线程的概念与区别了解吗? 这期,我们来聊一聊一个在Java并发编程中很重要的类:ThreadLocal 在多线程应用程序中,对共享变量进行读写的场景是很常见的。如果不使用一定的技术或方案,会引发各种线程安全的问题。常见解决线程安全的方式有synchronized、volatile等方式,但synchronized对性能的开销大,volatile不能保证原子性,所以这里介绍一个

YHJ 1万+

梦幻西游端游脚本开发实战:从易语言到大漠多线程全解析

本文详细解析了梦幻西游端游脚本开发的全流程,从易语言基础入门到大漠插件多线程实战。重点介绍了易语言中文编程优势、大漠插件图色识别技术,以及多线程控制台开发技巧,帮助开发者高效实现游戏自动化,提升脚本稳定性和执行效率。

weixin_29251567的博客 1059

如何使用ThreadLocal解决线程安全问题?

定义与用途ThreadLocal是一个Java类,它提供了一种将数据与线程关联的机制。每个线程都有一个独立的ThreadLocal实例,每个实例都可以存储不同的数据,互不干扰。通过为每个线程提供独立的变量副本,ThreadLocal避免了多线程之间的竞争条件,从而保证了线程安全。工作原理ThreadLocal内部使用一个ThreadLocalMap来存储每个线程的变量副本。ThreadLocalMap是一个自定义的Map,它的键是ThreadLocal实例,值是对应线程的变量副本。

Good_tea_h的博客 1706

告别眼疲劳!保姆级教程:给你的SecureCRT v8.7.2换上护眼高亮配色(附透明背景设置)

本文提供了一份详细的SecureCRT v8.7.2护眼高亮配色方案教程,帮助程序员缓解眼疲劳问题。通过科学调整配色方案、动态环境自适应设置以及字体渲染优化,显著提升终端使用的舒适度和工作效率。特别推荐Solarized Dark和One Dark Pro医学适配版配色方案,适合长时间编码工作。

weixin_42549496的博客 353

【Pix4d精品教程】Pix4d中央子午线细化设置(测区跨两个分带)

本文介绍了在Pix4d软件中通过修改中央子午线设置来解决跨分带测区刺点问题的方法。针对测区跨3度分带(如105°和108°之间)时像控点与靶标点偏移较大的情况,建议将中央子午线设为测区中心(如106.5°)。具体操作步骤包括:修改投影文件中的中央子午线参数,选择新的输出坐标系配置文件。该方法能有效提高像控点刺点效率,为航测内业数据处理提供便利。操作简单实用,适合大比例尺测图项目中跨分带测区的数据处理需求。

智慧空间实验室 5526

ThreadLocal线程安全示例及其原理

线程安全是多线程编程时的计算机程序代码中的一个概念。 在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。 多个线程访问同一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他操作,调用这个对象的行为都可以获得正确的结果,那么这个对象就是线程安全的。 ...

weixin_47053123的博客 5049

动态视频目标追踪系统:基于YOLOv11+DeepSORT的从入门到实战全流程指南

仅保留车辆类别(假设车辆类别ID为2)if det.class_index == 2: # 车辆类别ID通过本指南,你已完成从环境搭建数据准备模型训练到追踪系统与UI界面的全流程,搭建了一套完整的动态视频目标追踪系统。该系统在安防监控、交通管理等场景中具有实用价值,可实现目标的实时稳定追踪。未来,你可尝试结合多模态特征(如目标外观+运动特征)提升追踪鲁棒性,或探索轻量化模型部署(如TensorRT加速),让系统在边缘设备上也能高效运行。

LXY_LOVE36的博客 142

JAVA之ThreadLocal的用途(多线程安全)

什么是ThreadLocal 多线程访问同一个共享变量的时候容易出现并发问题,特别是多个线程对一个变量进行写入的时候,为了保证线程安全,一般在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性。 ThreadLocal是除了加锁这种同步方式之外的另一种保证多线程访问变量时的线程安全的方法;如果每个线程对变量的访问都是基于线程自己的变量这样就不会存在线程不安全问题。 在Java的多线程编程中,为保证多个线程对共享变量的安全访问,通常会使用synchronized来保证同一时刻只有一个线程对共享变量进行

★【World Of Moshow 郑锴】★ 1018

Altium Designer (AD) 设计软件高频面试题及参考答案(3万字长文)

在Altium Designer(AD)中,设计复用是一种关键的策略,它允许设计师在多个项目中重复使用经过验证的设计元素,如原理图符号、PCB布局、元器件封装和设计规则集。在Altium Designer (AD) 中,手动布线和交互式布线是PCB设计中常见的两种布线模式,它们提供了设计师对布线路径的直接控制,特别是在处理复杂或关键信号路径时尤为有用。在Altium Designer (AD) 中进行电路级仿真是一项重要的设计验证步骤,它允许设计师在实际制造之前对电路的行为进行预测和分析。

大模型大数据攻城狮的专栏 4781

Motoman机器人离线编程——Motocom32开发简介

欢迎关注Jungle的Motoman机器人离线编程专栏系列文章: Motoman机器人离线编程——Motocom32开发简介 Motoman机器人离线编程——Visio Studio环境配置 Motoman机器人离线编程——Motocom32库函数的使用与封装 Motoman机器人离线编程——Motocom32参考文献及注意事项 Motoman机器人离线编程——MotocomES介绍 ...

冯Jungle的个人博客 8713

18. 线程数据共享和安全 -ThreadLocal

18.1 什么是 ThreadLocal ThreadLocal 的作用,可以实现在同一个线程数据共享, 从而解决多线程数据安全问题. ThreadLocal 可以给当前线程关联一个数据(普通变量、对象、数组)set 方法 [源码!] ThreadLocal 可以像 Map 一样存取数据,key 为当前线程, get 方法 每一个 ThreadLocal 对象,只能为当前线程关联一个数据,如果要为当前线程关联多个数 据,就需要使用多个 ThreadLocal 对象实例 每个 ThreadLocal 对象实

要学就学灰太狼的博客 291

Firefox卸载卡住不动的解决方案

本文主要介绍了Firefox卸载卡住不动的解决方案,希望能对使用Windows的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 15万+

理解ThreadLocal,实现安全的多线程

通通透透理解ThreadLocal,实现安全的多线程 www.diybl.com 时间 : 2010-10-26 作者:佚名 编辑:fnw 点击: 1726 [ 评论 ] - - 我们知道Spring通过各种DAO模板类降低了开发者使用各种数据持久技术的难度。这些模板类都是线程安全的,也就是说,多个DAO可以复用同一个模板实例而不会发生冲突。 我们使用模板类访问底层数据...

lvwenwen 124

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

通通透透理解ThreadLocal,实现安全的多线程

我们知道Spring通过各种DAO模板类降低了开发者使用各种数据持久技术的难度。这些模板类都是线程安全的,也就是说,多个DAO可以复用同一个模板实例而不会发生冲突。我们使用模板类访问底层数据,根据持久化技术的不同,模板类需要绑定数据连接或会话的资源。但这些资源本身是非线程安全的,也就是说它们不能在同一时刻被多个线程共享。虽然模板类通过资源池获取数据连接或会话,但资源池本身解决的是数据连接或

波波的专栏 1435

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Java ThreadLocal

ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它...

iteye_19360的博客 145

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

ThreadLocal

ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它

syj0301的专栏 420

java中ThreadLocal类的使用

ThreadLocal是解决线程安全问题一个很好的思路,ThreadLocal类中有一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值对应线程的变量副本,由于Key值不可重复,每一个“线程对象”对应线程的“变量副本”,而到达了线程安全。 我们知道Spring通过各种DAO模板类降低了开发者使用各种数据持久技术的难度。这些模板类都是线程安全的,也就是说,多个DAO可以复

ichsonx的专栏 732

怎么实现springMVC 多线程并发

我们知道Spring通过各种DAO模板类降低了开发者使用各种数据持久技术的难度。这些模板类都是线程安全的,也就是说,多个DAO可以复用同一个模板实例而不会发生冲突。 我们使用模板类访问底层数据,根据持久化技术的不同,模板类需要绑定数据连接或会话的资源。但这些资源本身是非线程安全的,也就是说它们不能在同一时刻被多个线程共享。 虽然模板类通过资源池获取数据连接或会话,但资源池本身解决的是数据连接或会话

1万+

深挖ThreadLocal

ThreadLocal是什么 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它

逆风奔跑。。不要去考虑什么天赋异禀,一切都来自经历和渴望。 43万+

ThreadLocal定义、作用

概述       我们知道Spring通过各种DAO模板类降低了开发者使用各种数据持久技术的难度。这些模板类都是线程安全的,也就是说,多个DAO可以复用同一个模板实例而不会发生冲突。       我们使用模板类访问底层数据,根据持久化技术的不同,模板类需要绑定数据连接或会话的资源。但这些资源本身是非线程安全的,也就是说它们不能在同一时刻被多个线程共享。       虽然模板类通过资源

lipc_的博客 693

ThreadLocal笔记

ThreadLocal笔记 网上搜索的结果,实践验证后记录 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些。 当使用ThreadLocal维护变量时,Thre

CenturyMagus的专栏 911

简单的理解ThreadLocal

线程安全,很好使的一种方法 java.lang.ThreadLocal的诞生就是为了解决多线程并发问题。 举例子 不使用ThreadLocal 不使用ThreadLocal实现并发,可以发现各个线程之间共享了number 变量,如果我不想共享,使得每个线程都独占该咋办呢。 interface Sequence{ int getNumber(); } class ClientT...

摩尔的博客 508

理解ThreadLocal

<br />ThreadLocal是什么<br />早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。<br />ThreadLocal很容易让人望文生义,想当然地认为是一个“本地线程”。其实,ThreadLocal并不是一个Thread,而是Thread的局部变量,也许把它命名为ThreadLocalVariable更容易让人理解一些。<br />当使用Threa

526
上一篇: ThreadLocal类的工作原理
下一篇: 关于oracle中的通用函数的点滴
爪爪的瓜瓜
博客等级 码龄14年 5粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值