初见 ThreadLocal 类
这个类能够将一个对象和一个线程绑定起来,我的理解就是他维持了一个Map<Thread, T>集合。


之所以写这个类是因为 DBUtils 工具类,在 JavaEE 经典三层结构中对于事务的操作,不方便放在 DAO 层,因为具有侵入性,只适合放在 Service层开启事务,但是由于要调用 DAO 中不同的方法来完成一个事务,就涉及到 conn 对象的传递,因为要保证是同一个 conn 对象在操作事务,要不然就会出乱子了,就会想到将 conn 对象当成参数传递给 ADO 层的若干方法,但是有时候连 Service 都没有 conn 对象的持有,更别说当成参数传递给 DAO 层了,但是想一想,执行一个事务的线程肯定是同一个线程,这样就可以用上ThreadLocal 类了,在使用连接池时就将 conn 对象和当前线程绑定,在之后的 ADO 中获取 conn 对象时,也是通过连接池获取 conn 对象,此时也肯定是同一个 conn 对象。
这个ThreadLocal类中提供的方法不多,我下面使用的就是 get/set 方法

下面是一个转账的事务:(数据库中 account 表有三个字段:id, name, money)
下面是JDBCUtils工具类中核心代码:
private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
private static final ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
// 获得连接:
public static Connection getConnection() throws SQLException{
Connection conn = tl.get();
if(conn == null){
conn = dataSource.getConnection();
tl.set(conn);
}
return conn;
} // 开启事务的方法:
public static void beginTransaction() throws SQLException{
Connection conn = tl.get();
if(conn == null){
conn = dataSource.getConnection();
tl.set(conn);
}
conn.setAutoCommit(false);
} // 事务提交的方法:
public static void commitTransaction() throws SQLException{
Connection conn = tl.get();
conn.commit();
} // 事务回滚的方法;
public static void rollbackTransction() throws SQLException{
Connection conn = tl.get();
conn.rollback();
}
Service中的测试代码:
/**
* @param from :转出账号
* @param to :转入账号
* @param money :转账金额
*/
public void transfer(String from,String to,Double money){
AccountDao accountDao = new AccountDao();
try {
JDBCUtils.beginTransaction();
accountDao.out(from, money);
accountDao.in(to, money);
JDBCUtils.commitTransaction();
} catch (SQLException e) {
try {
JDBCUtils.rollbackTransction();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
@Test
public void demo1(){
AccountServicce accountServicce = new AccountServicce();
accountServicce.transfer("aaa", "bbb", 1000d);
}
ADO 中完成事务中两个部分的方法:
public void out(String from,Double money){
Connection conn = null;
PreparedStatement stmt = null;
try{
conn = JDBCUtils.getConnection();
String sql = "update account set money = money - ? where name = ?";
stmt = conn.prepareStatement(sql);
stmt.setDouble(1, money);
stmt.setString(2, from);
stmt.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}
}
public void in(String to,Double money){
Connection conn = null;
PreparedStatement stmt = null;
try{
conn = JDBCUtils.getConnection();
String sql = "update account set money = money + ? where name = ?";
stmt = conn.prepareStatement(sql);
stmt.setDouble(1, money);
stmt.setString(2, to);
stmt.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}
}
用过 DBUtils 的博友肯定知道,他里面也是使用了两种方式,一种是绑定到线程(绑定过程是由连接池完成的),一种是传递 conn 对象,前者适用于非事务类的 sql 操作,后者适合事务 sql 操作(因为事务需要自己手动开启,提交或回滚,需要在 Server 层获取到 conn 对象)。
这个类在 struts2 也有用到,在绑定动作 action对象所在线程和其数据集合对象 ActionContext就会用到这个类,这也是 struts2 相比 struts1 线程安全的原因了;这里的 ActionContext 也就是 contextMap 了,ognl 表达式的数据中心。
在获取当前 action(也是当前线程) 的 Actioncontext 对象时使用的是下面的方法:
总是不够完善,希望有人能指出我的错误。
初见 ThreadLocal 类的更多相关文章
- ThreadLocal类详解:原理、源码、用法
以下是本文目录: 1.从数据库连接探究 ThreadLocal 2.剖析 ThreadLocal 源码 3. ThreadLocal 应用场景 4. 通过面试题理解 ThreadLocal 1.从数据 ...
- 用ThreadLocal类实现线程安全的正确姿势
大家通常知道,ThreadLocal类可以帮助我们实现线程的安全性,这个类能使线程中的某个值与保存值的对象关联起来.ThreadLocal提供了get与set等访问接口或方法,这些方法为每个使用该变量 ...
- Java线程与并发库高级应用-线程范围内共享数据ThreadLocal类
1.线程范围内共享变量 1.1 前奏: 使用一个Map来实现线程范围内共享变量 public class ThreadScopeShareData { static Map<Thread, In ...
- 2015年11月26日 Java基础系列(三)ThreadLocal类初级学习
序,ThreadLocal类是为了解决多线程的安全问题.线程安全的意思也就是说每个线程操作自己的变量,不要对其他线程的值造成影响. 在很多情况下,ThreadLocal比直接使用synchronize ...
- ThreadLocal类的实现用法
ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名为Thread ...
- 深入研究java.lang.ThreadLocal类(转)
引用:http://lavasoft.blog.51cto.com/62575/51926/ 一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并 ...
- 深入研究java.lang.ThreadLocal类
一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许 ...
- ThreadLocal类的理解
首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的.各 ...
- Java多线程——ThreadLocal类
一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名 ...
随机推荐
- html 一般标签 常用标签 表格
body的属性: bgcolor 页面背景色 background 背景壁纸.图片 text 文字颜色 top ...
- shell编程其实真的很简单(三)
通过前两篇文章,我们掌握了shell的一些基本写法和变量的使用,以及基本数据类型的运算.那么,本次就将要学习shell的结构化命令了,也就是我们其它编程语言中的条件选择语句及循环语句. 不过,在学习s ...
- MyEclipse - 解决 MyEclipse build workspace慢,validation javascript更慢的问题
在这个过程中对.projet文件进行了跟踪比对,总算发现这个Build的时候进行Validation是从哪里定义的了.似乎因为我的项目是基于ExtJS2.0.2的web project,所以会提示打开 ...
- Android音频焦点详解(上)
转载请注明出处:http://www.cnblogs.com/landptf/p/6384112.html 2017年开年第一篇博客,很早就想总结一下Android音频的相关知识.今天我们先来看一下音 ...
- experss框架—基础认识
express简介: Express是一个简洁.灵活的node.js Web应用开发框架, 它提供一系列强大的功能,比如:模板解析.静态文件服务.中间件.路由控制等等,并且还可以使用插件或整合其他模块 ...
- 10步完成Abp(.net core)+Vue的Demo?
1.去abp官网生成项目,选择.net core1.x版本 2.Nuget还原包,需装dotnet core1.1等. 3.新增一个entity,并加入到上下文中 4.然后cmd命令行工具切换到项目 ...
- CAN信号值解析
本文提供一种可以解析CAN信号各信号值的一种方法并进行说明. 一般情况下,高端一点的设备会计算每一个信号的值,但是接受到CAN信号的报文实际上有各种情况,如何通过设定的起始位和数据长度来获取某一信号的 ...
- js与android webview交互
0x01 js调用java代码 android webview中支持通过添加js接口 webview.addJavascriptInterface(new JsInteration(), " ...
- 一个想法(续六):IT联盟创业计划:如何进行找钱、寻人、做事?
前言: 不知时间过的快,或是慢,一周过去了,在这一周,基本是围绕着创业这事在折腾. 也在看一些和创业相关的文章,不小心就看到了dudu在2007年呼喊创业的口号. 于是把他那一年的博文都给看了: 看着 ...
- [NOI2007]货币兑换Cash(DP+动态凸包)
第一次打动态凸包维护dp,感觉学到了超级多的东西. 首先,set是如此的好用!!!可以通过控制一个flag来实现两种查询,维护凸包和查找斜率k 不过就是重载运算符和一些细节方面有些恶心,90行解决 后 ...

