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,共同操作 ...
随机推荐
- mysql 安装为服务 ,mysql.zip 安装为服务,mysql搬移迁移服务器安装为服务
从服务器A打包到服务器B后,在服务器B中运行安装服务命令,可自定义服务名,一台服务器上可装N个MySql实例 mysqld --install MySQL_0001 --defaults-file=D ...
- 微服务, 架构, 服务治理, 链路跟踪, 服务发现, 流量控制, Service Mesh
微服务, 架构, 服务治理, 链路跟踪, 服务发现, 流量控制, Service Mesh 微服务架构 本文将介绍微服务架构和相关的组件,介绍他们是什么以及为什么要使用微服务架构和这些组件.本文侧 ...
- SQL Server MERGE(合并)语句
如何使用SQL Server MERGE语句基于与另一个表匹配的值来更新表中的数据. SQL Server MERGE语句 假设有两个表,分别称为源表和目标表,并且需要根据与源表匹配的值来更新目标表 ...
- 基于C++ STL sort函数对c++ string 进行字符串的局部排序
Paypal笔试挂了,因为好久没有在leedcode之类的网上写代码,字符输入调了半天,时间都用光了.... Description: 有一个字符串,现在对其进行多次局部排序,例如str=" ...
- mysql 多个字段的查询处理
https://blog.csdn.net/zzzgd_666/article/details/81101548
- Elasticsearch进阶篇(一)~head插件的安装与配置
1.安装node.js 1.1.通过官网下载二进制安装包 https://nodejs.org/en/download/ 选择对应的版本,右键复制下载链接,进入linux目录,切换到要安装目录的磁盘. ...
- Ubuntu 固定自己的IP
使用以下命令 sudo vi /etc/network/interfaces 以下方文件内容进行覆盖 # interfaces(5) file used by ifup(8) and ifdown( ...
- vue-cli中轮播图vue-awesome-swiper使用方法
1 npm 安装 npm install vue-awesome-swiper --save 2在所用的组件中引入 import 'swiper/dist/css/swiper.css' import ...
- Java 函数式编程和Lambda表达式
1.Java 8最重要的新特性 Lambda表达式.接口改进(默认方法)和批数据处理. 2.函数式编程 本质上来说,编程关注两个维度:数据和数据上的操作. 面向对象的编程泛型强调让操作围绕数据,这样可 ...
- 基于hystrix的线程池隔离
hystrix进行资源隔离,其实是提供了一个抽象,叫做command,就是说,你如果要把对某一个依赖服务的所有调用请求,全部隔离在同一份资源池内 对这个依赖服务的所有调用请求,全部走这个资源池内的资源 ...