? (2) AccountService类的修改:不需要传递connection对象
package com.itheima.transfer.service;import com.itheima.transfer.dao.AccountDao;import com.itheima.transfer.utils.JdbcUtils;import java.sql.Connection;public class AccountService {public boolean transfer(String outUser, String inUser, int money) {AccountDao ad = new AccountDao();try {Connection conn = JdbcUtils.getConnection();//开启事务conn.setAutoCommit(false);// 转出 : 这里不需要传参了 !ad.out(outUser, money);// 模拟转账过程中的异常//int i = 1 / 0;// 转入ad.in(inUser, money);//事务提交JdbcUtils.commitAndClose();} catch (Exception e) {e.printStackTrace();//事务回滚JdbcUtils.rollbackAndClose();return false;}return true;}}
? (3) AccountDao类的修改:照常使用
package com.itheima.transfer.dao;import com.itheima.transfer.utils.JdbcUtils;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.SQLException;public class AccountDao {public void out(String outUser, int money) throws SQLException {String sql = "update account set money = money - ? where name = ?";Connection conn = JdbcUtils.getConnection();PreparedStatement pstm = conn.prepareStatement(sql);pstm.setInt(1,money);pstm.setString(2,outUser);pstm.executeUpdate();//照常使用//JdbcUtils.release(pstm,conn);JdbcUtils.release(pstm);}public void in(String inUser, int money) throws SQLException {String sql = "update account set money = money + ? where name = ?";Connection conn = JdbcUtils.getConnection();PreparedStatement pstm = conn.prepareStatement(sql);pstm.setInt(1,money);pstm.setString(2,inUser);pstm.executeUpdate();//JdbcUtils.release(pstm,conn);JdbcUtils.release(pstm);}}
2.3.2 ThreadLocal方案的好处从上述的案例中我们可以看到 , 在一些特定场景下 , ThreadLocal方案有两个突出的优势:
- 传递数据 : 保存每个线程绑定的数据 , 在需要的地方可以直接获取, 避免参数直接传递带来的代码耦合问题
- 线程隔离 : 各线程之间的数据相互隔离却又具备并发性 , 避免同步方式带来的性能损失
3.1常见的误解? 通常 , 如果我们不去看源代码的话 , 我猜
ThreadLocal
是这样子设计的:每个ThreadLocal
类都创建一个Map
, 然后用线程的ID threadID
作为Map
的key
, 要存储的局部变量作为Map
的value
, 这样就能达到各个线程的局部变量隔离的效果 。这是最简单的设计方法 , JDK最早期的ThreadLocal
就是这样设计的 。3.2核心结构? 但是 , JDK后面优化了设计方案 , 现时JDK8
ThreadLocal
的设计是:每个Thread
维护一个ThreadLocalMap
哈希表 , 这个哈希表的key
是ThreadLocal
实例本身 , value
才是真正要存储的值Object
。? (1) 每个Thread线程内部都有一个Map (ThreadLocalMap)? (2) Map里面存储ThreadLocal对象(key)和线程的变量副本(value)? (3)Thread内部的Map是由ThreadLocal维护的 , 由ThreadLocal负责向map获取和设置线程的变量值 。? (4)对于不同的线程 , 每次获取副本值时 , 别的线程并不能获取到当前线程的副本值 , 形成了副本的隔离 , 互不干扰 。

文章插图
3.3 这样设计的好处? 这个设计与我们一开始说的设计刚好相反 , 这样设计有如下两个优势:
经验总结扩展阅读
- 为啥有的票直达还得换座
- 冰冻的火锅丸子煮多久
- 之八 2流高手速成记:基于Sentinel实现微服务体系下的限流与熔断
- 8k和a3纸的一样大么
- chrome工具调试
- 蓝色糖心玛瑙是天然的吗
- 马克笔和记号笔的区别
- 想开发DAYU200,我教你
- 火车z,k,c,t开头的代表什么?
- 1.5*1.8的床多大 1.5米的床用多大的床单