多线程之ThreadLocal类
Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量。
采用空间换时间,它用于线程间的数据隔离,为每一个使用该变量的线程提供一个副本,每个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突。
ThreadLocal类中维护一个Map,用于存储每一个线程的变量副本,Map中元素的键为线程对象,而值为对应线程的变量副本。
ThreadLocal在Spring中发挥着巨大的作用,在管理Request作用域中的Bean、事务管理、任务调度、AOP等模块都出现了它的身影。
Spring中绝大部分Bean都可以声明成Singleton作用域,采用ThreadLocal进行封装,因此有状态的Bean就能够以singleton的方式在多线程中正常工作了。
/*
* 学生类
* 此处为一个bean
*/
public class Student {
public int age = 0; public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
}
}
主程序:
import java.util.Random; /*
* 多线程下测试程序
*/
public class ThreadLocalDemo implements Runnable {
//创建线程局部变量studentLocal,在后面你会发现用来保存student对象
private final static ThreadLocal studentLocal = new ThreadLocal(); public static void main(String[] args) {
ThreadLocalDemo td = new ThreadLocalDemo();
//线程一
Thread t1 = new Thread(td,"a");
//线程二
Thread t2 = new Thread(td,"b");
t1.start();
t2.start();
}
@Override
public void run() {
accessStudent();
// TODO Auto-generated method stub
}
/*
*实例业务方法,用来测试
*/
public void accessStudent(){
//获取当前线程的名字
String currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " is running");
//产生一个随机数并打印
Random random = new Random();
int age = random.nextInt(100);
System.out.println("Tread " + currentThreadName + " set age to:" + age);
//获取一个student对象,并将随机年龄插入到对象的属性中
//获取对象的方式,采用本地获取对象
Student student = getStudent();
student.setAge(age);
System.out.println("Thread " + currentThreadName + " 第一次读取年龄为:" + student.getAge());
try {
Thread.sleep(5000); } catch (InterruptedException ex) {
ex.printStackTrace(); // TODO: handle exception
}
System.out.println("Thread" + currentThreadName + " 第二次读取年龄为:" + student.getAge());
}
//此处为重点
private Student getStudent() {
//获取本线程变量并强制转换为Student类型
Student student= (Student) studentLocal.get();
//线程首次执行的时候,studentLocal.get()肯定为null
if(student == null){
//创建一个Student对象,并保存到本地的线程变量StudentLocal中
student = new Student();
studentLocal.set(student); }
// TODO Auto-generated method stub
return student;
}
}
运行结果:
b is running
a is running
Tread b set age to:49
Tread a set age to:37
Thread b 第一次读取年龄为:49
Thread a 第一次读取年龄为:37
Thread b 第二次读取年龄为:49
Thread a 第二次读取年龄为:37
可以看到a、b两个线程age在不同时刻打印的值是完全相同的。这个程序通过妙用ThreadLocal,既实现多线程并发,游兼顾数据的安全性
文章出自:http://blog.51cto.com/lavasoft/51926,代码为亲自手撕
多线程之ThreadLocal类的更多相关文章
- Java基础-进程与线程之Thread类详解
Java基础-进程与线程之Thread类详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.进程与线程的区别 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 ...
- Java并发编程之ThreadLocal类
ThreadLocal类可以理解为ThreadLocalVariable(线程局部变量),提供了get与set等访问接口或方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回当 ...
- 多线程之ThreadLocal(转)
相信读者在网上也看了很多关于ThreadLocal的资料,很多博客都这样说:ThreadLocal为解决多线程程序的并发问题提供了一种新的思路:ThreadLocal的目的是为了解决多线程访问资源时的 ...
- 多线程之ThreadLocal
Java并发编程:深入剖析ThreadLocal 想必很多朋友对ThreadLocal并不陌生,今天我们就来一起探讨下ThreadLocal的使用方法和实现原理.首先,本文先谈一下对ThreadLoc ...
- Java多线程之ThreadLocal总结2
ThreadLocal是什么 早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地 ...
- Java线程之ThreadLocal
翻译:https://www.journaldev.com/1076/java-threadlocal-example?utm_source=website&utm_medium=sideba ...
- Java多线程之ThreadLocal总结
原贴地址:http://www.cnblogs.com/zhengbin/p/5674638.html 阅读目录 官方对ThreadLocal的描述: <Thinking in Java> ...
- java多线程之ThreadLocal
ThreadLocal为每个线程保存变量,以保证数据同步. package Thread.Common; import java.util.Random; import java.util.concu ...
- 多线程之Parallel类
Parallel类是对线程的一个抽象.该类位于System.Threading.Tasks名称空间中,提供了数据和任务并行性. Paraller类定义了数据并行地For和ForEach的静态方法,以及 ...
随机推荐
- CTFshow-萌新赛逆向_flag白给
查看题目信息 下载后得到一个flag.exe文件,进行测试 使用PEiD查壳 发现一个upx的壳 使用命令进行解壳 upx -d 拿到一个无壳的程序 放进OD打开,查找关键词 发现信息 成功拿到序列号 ...
- SAP内表类型及其数据读取效率评估
内表大概分3种: 1.标准表standard tables:如果不指定BINARY SEARCH附加选项,则默认为线性查找(linear search),既一条一条的查找. 2.排序表(sorted ...
- OpenStack各组件的常用命令
openstack命令 openstack-service restart #重启openstack服务 openstack endpoint-list #查看openstack的 ...
- 温习数据算法—js滑块验证码
前言 大多数的应用软件都需要输入一些验证码,验证码的样式也多种多样. 比如抢票,提交订单需要验证码,很多人就纳闷了,怎么还需要验证码呢?这不是浪费时间嘛. 存在即合理,合理就是现实的. 源码下载地址+ ...
- XV6学习(2)Lab syscall
实验的代码放在了Github上. 第二个实验是Lab: system calls. 这个实验主要就是自己实现几个简单的系统调用并添加到XV6中. XV6系统调用 添加系统调用主要有以下几步: 在use ...
- 使用Jmeter对SHA1加密接口进行性能测试
性能测试过程中,有时候会遇到需要对信息头进行加密鉴权,下面我就来介绍如何针对SHA1加密鉴权开发性能测试脚本1.首先了解原理,就是需要对如下三个参数进行SHA1加密,(AppSecret + Nonc ...
- day132:2RenMJ:MJ需求文档&MJ游戏流程&Egret白鹭引擎安装&TypeScript简要介绍
目录 1.麻将产品需求文档 2.麻将游戏流程 3.Egret白鹭引擎 4.TypeScript简要了解 5.TypeScript快速入门 1.麻将产品需求文档 1.麻将术语 1.名词术语 牌⼦: 序数 ...
- CSSmargin击穿问题(子元素margin-top会影响父元素)
最近写一个H5页面的时候发现了这个被忽视的问题,一时没想到什么原因,搜了半天,记录一下,方便他人踩坑.唉,有些东西不用就忘. 一.问题描述 <div class="container& ...
- ResponseEntity和@ResponseBody以及@ResponseStatus区别
看的迷迷糊糊的 https://www.jdon.com/springboot/responseentity.html
- HBase协处理器加载过程(1.2.x)
一.首先来看ObserverCoprocessor:1.观察者协处理器的静态加载的配置是在hbase-site.xml中配置如下属性:通过hbase.coprocessor.region.classe ...