ThreadLocal(在一个线程中共享数据)
ThreadLocal
在"事务传递Connection"参数案例中,我们必须传递Connection对象,才可以完成整个事务操作.如果不传递参数,是否可以完成?在JDK中给我们提供了一个工具类ThreadLocal.此类可以在一个线程中共享数据
java.lang.ThreadLocal:该类提供了线程局部(thread-local)变量,用于在当前线程中共享数据.
ThreadLocal
java.lang.ThreadLocal该类提供了线程局部(thread-local)变量,用于在当前线程中共享数据,ThreadLocal工具类底层就是一个相当于一个Map,key存放的当前线程,value存放需要共享的数据.
package com.qingmu; /**
* @Auther:qingmu
* @Description:脚踏实地,只为出人头地
* @Date:Created in 16:08 2019/5/25
*/
public class ThreadLocalTest {
public static void main(String[] args) {
ThreadLocal<String> stringThreadLocal = new ThreadLocal<>();
stringThreadLocal.set("青木");
System.out.println(stringThreadLocal.get()); new Thread(()->
System.out.println(stringThreadLocal.get())).start();
}
}
结果为:
总结:向ThreadLocal中添加的数据只能在当前线程中使用.
小案例的应用:
工具类
public class C3P0Utils {
//创建一个C3P0的连接池对象(使用c3p0-config.xml中default-config标签中对应的参数)
public static DataSource ds = new ComboPooledDataSource();
//给当前线程绑定 连接
private static ThreadLocal<Connection> local = new ThreadLocal<Connection>();
/**
* 获得一个连接
*/
public static Connection getConnection(){
try {
//#1从当前线程中, 获得已经绑定的连接
service层
Connection conn = local.get();
if(conn == null){
//#2 第一次获得,绑定内容 – 从连接池获得
conn = ds.getConnection();
//#3 将连接存 ThreadLocal
local.set(conn);
}
return conn; //获得连接
} catch (Exception e) {
//将编译时异常 转换 运行时 , 以后开发中运行时异常使用比较多的。
throw new RuntimeException(e);
/*
类与类之间 进行数据交换时,可以使用return返回值。也可以使用自定义异常返回值,调用者try{}
catch(e){ e.getMessage() 获得需要的数据}
此处可以编写自定义异常。
*/
//throw new MyConnectionException(e);
}
}
}
service层
public class AccountService {
/**
* 事务管理方式:向下传递Connection。有侵入性。使用DBUtils
* 业务层事务管理转账的方法
* @param from
* @param to
* @param money
*/
public void transfer(String from, String to, double money) {
//调用dao层
AccountDao accountDao = new AccountDao();
//DBUtils进行事务处理的原理,是在Service层获得连接,以保证事务处理过程中的Connection对象为同一个Connection。
//因为必须保证连接为同一个连接,所以在业务层获得连接,再将连接传递到持久层,代码具有侵入性。
//DBUtils使用的方法
Connection conn = null;
try {
//获得连接
conn = C3P0Utils.getConnection();
//设置事务不自动提交
conn.setAutoCommit(false);
//调用持久层
accountDao.outMoney(from,money);
//如果有异常
//int a = 1 / 0 ;
accountDao.inMoney(to,money);
//提交事务,并安静的关闭连接
DbUtils.commitAndCloseQuietly(conn);
} catch (SQLException e) {
//有异常出现时,回滚事务,并安静的关闭连接
DbUtils.rollbackAndCloseQuietly(conn);
e.printStackTrace();
}
}
}
dao层
public class AccountDao {
/**
* 付款方法
* @param from 付款人
* @param money 金额
*/
public void outMoney(String from, double money) {
QueryRunner qr = new QueryRunner();
try {
Connection conn = C3P0Utils.getConnection();
String sql = "update account set money = money - ? where name = ?";
qr.update(conn, sql, money,from);
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 收款方法
* @param to 收款人
* @param money 金额
*/
public void inMoney(String to, double money) {
QueryRunner qr = new QueryRunner();
try {
Connection conn = C3P0Utils.getConnection();
String sql = "update account set money = money + ? where name = ?";
qr.update(conn, sql, money,to);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
ThreadLocal(在一个线程中共享数据)的更多相关文章
- Disruptor 线程间共享数据无需竞争
队列的作用是缓冲 缓冲到 队列的空间里.. 线程间共享数据无需竞争 原文 地址 作者 Trisha 译者:李同杰 LMAX Disruptor 是一个开源的并发框架,并获得2011 Duke’ ...
- 参数在一个线程中各个函数之间互相传递的问题(ThreadLocal)
ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源. 一个ThreadLocal变量虽然是 ...
- 详解 Qt 线程间共享数据(用信号槽方式)
使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的. Qt 线程间共享数据是本文介绍的内容,多的不说,先来啃内容.Qt线程间共享 ...
- Qt学习:线程间共享数据(使用信号槽传递数据,必须提前使用qRegisterMetaType来注册参数的类型)
Qt线程间共享数据主要有两种方式: 使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的: 使用singal/slot机制,把数据 ...
- 使用ThreadLocal在线程内部传递数据
最近在项目中使用到了JDK提供的线程池,遇到了在多线程环境下在线程内部共享数据的问题 使用ThreadLocal 来解决线程内部共享数据的问题 定义BO package com.unicom.uclo ...
- 详解 Qt 线程间共享数据(使用signal/slot传递数据,线程间传递信号会立刻返回,但也可通过connect改变)
使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的. Qt 线程间共享数据是本文介绍的内容,多的不说,先来啃内容.Qt线程间共享 ...
- Java基础-线程操作共享数据的安全问题
Java基础-线程操作共享数据的安全问题 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.引发线程安全问题 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运 ...
- JAVA多线程提高四:多个线程之间共享数据的方式
多个线程访问共享对象和数据的方式 如果每个线程执行的代码相同,可以使用同一个Runnable对象,这个Runnable对象中有那个共享数据,例如,买票系统就可以这么做. 如果每个线程执行的代码不同,这 ...
- Java并发基础09. 多个线程间共享数据问题
先看一个多线程间共享数据的问题: 设计四个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1. 从问题来看,很明显涉及到了线程间通数据的共享,四个线程共享一个 data,共同操作 ...
随机推荐
- IBM X3650 M4 安装 Windows Server 2008 R2
1 准备好 Windows Server 2008 R2 安装用的U盘 2 采用PowerISO制作启动U盘: 或者用Rufus做启动U盘. 3 接上启动U盘 4 设置Bios启动模式为 UEFI ...
- 【Spring Cloud学习之一】微服务架构
一.网站架构模式发展 单体应用-->SOA-->微服务 1.分布式项目与项目集群分布式项目:根据业务需求进行拆分成N个子系统,多个子系统相互协作才能完成业务流程子系统之间通讯使用RPC远程 ...
- codesmith设置mysql的连接字符串
.net core,codesmith连不上 server=192.168.3.240;Initial Catalog=tpmdb;User=root;Password=root .net frame ...
- Win10最详细的优化设置 完美解决磁盘100%占用
1.用360优化win10后开不了机的问题原因是禁用了三个服务:在360应用软件服务里dmwappushsvc.diagnsticsTrackingservice.coreMessaging这三个要开 ...
- SQL Server 索引的最佳实践
索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就获取到的,很多的技术人员因为不恰当的创建索引,最后使得其效果适得其 ...
- Java开发笔记(一百四十九)引入预报告的好处
前面介绍了各种SQL语句的调用过程,虽然例子代码写死了每个SQL串,但是完全可以把查询条件作为方法参数传进来.比如现在想删除某个课程的教师记录,那么在编写删除方法时,就把课程名称作为该方法的一个输入参 ...
- 前端框架之Bootstrap框架
下载地址:https://v3.bootcss.com/,下载Bootstrap3版本 下载之后把文件中不需要的文件都删掉 需要获取的样式代码,可以直接从这些地方找到,然后复制 一.HTML页面导入文 ...
- Go基础编程实践(三)—— 日期和时间
日期和时间 package main import ( "fmt" "time" ) func main() { // 获取当前时间 current := ti ...
- Python输错4次用户名密码需要输入验证码
time = 0 login_success = False USER_NAME = "alex" PWD = "alex123" CHECK_CODE = & ...
- es常用操作
1.查看所有索引 _cat/indices?v 2.删除索引 DELETE my_index 3.查询缓存 curl /my_index/_search?request_cache=true' -d' ...