本文以数据库操作Dao为例进行描述ThreadLocal的使用,如下是一个反例:

package com.daxin.threadlocal.dao;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement; public class UserDaoErrorDemo { // ①一个非线程安全的变量
private Connection conn; /**
* addUser在并发时候关于事务的提交容易出现错乱
*/
public void addUser() {
try { // ②引用非线程安全变量
conn.setAutoCommit(false);
Statement stat = conn.createStatement();
stat.executeQuery("sql");
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
}

 

上面存在线程安全问题,在多个线程进行事务提交时候会出现错乱。因此可以通过如下方案:

package com.daxin.threadlocal.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement; /**
* 模拟数据库连接管理器
*
* @author liuguangxin
*
*/
class ConnectionManager { static String driverName = "";
static String url = "";
static String user = "";
static String password = ""; public static Connection getConnection() { try {
return DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
} }
/**
*
* @author liuguangxin
*
*/
public class UserDao { // ①使用ThreadLocal保存Connection变量
// 由于Dao通产刚在系统中是单例的,因此可以被多个线程共享,因此connThreadLocal也是被多个线程共享的。
private ThreadLocal<Connection> connThreadLocal = new ThreadLocal<Connection>(); public Connection getConnection() {
// ②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection, 并将其保存到线程本地变量中。
if (connThreadLocal.get() == null) {
Connection conn = ConnectionManager.getConnection();
connThreadLocal.set(conn);
return conn;
} else {
// ③直接返回线程本地变量
return connThreadLocal.get();
}
} public void addUser(String userName, String passWord) { Connection conn = getConnection();
Statement stmt = null;
try {
conn.setAutoCommit(false);
stmt = conn.createStatement();
// 伪代码
stmt.executeQuery("insert into user ....");
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
} finally {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} } }

  

Java ThreadLocal的使用案例的更多相关文章

  1. Java虚拟机类加载机制——案例分析

    转载: Java虚拟机类加载机制--案例分析   在<Java虚拟机类加载机制>一文中详细阐述了类加载的过程,并举了几个例子进行了简要分析,在文章的最后留了一个悬念给各位,这里来揭开这个悬 ...

  2. Java学生管理系统项目案例

    这是一个不错的Java学生管理系统项目案例,希望能够帮到大家的学习吧. 分代码如下 package com.student.util; import java.sql.Connection; impo ...

  3. Java ThreadLocal的使用

    Java中的ThreadLocal类允许我们创建只能被同一个线程读写的变量.因此,如果一段代码含有一个ThreadLocal变量的引用,即使两个线程同时执行这段代码,它们也无法访问到对方的Thread ...

  4. Java多态面试题案例几解题思路

    ---恢复内容开始--- Java多态面试题案例几解题思路 这道题是来自别人,先开始看到题很懵,后来有自己的思路: class A { public String show(D obj){ retur ...

  5. java基础-多线程应用案例展示

    java基础-多线程应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.两只熊,100只蜜蜂,蜜蜂每次生产的蜂蜜量是1,罐子的容量是30,熊在罐子的蜂蜜量达到20的时候 ...

  6. Java基础-数据类型应用案例展示

    Java基础-数据类型应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.把long数据转换成字节数组,把字节数组数据转换成long. /* @author :yinz ...

  7. Java ThreadLocal 源代码分析

    Java ThreadLocal 之前在写SSM项目的时候使用过一个叫PageHelper的插件 可以自动完成分页而不用手动写SQL limit 用起来大概是这样的 最开始的时候觉得很困惑,因为直接使 ...

  8. JAVA WEB项目开发案例精粹

    http://www.blogjava.net/zongbao/archive/2012/07/24/383884.htmlJAVA WEB项目开发案例精粹.pdf main Alt + / => ...

  9. java threadLocal的初探

    在网上找了半天,终于找到一篇靠谱的文章了. 文章地址:http://qifuguang.me/2015/09/02/[Java%E5%B9%B6%E5%8F%91%E5%8C%85%E5%AD%A6% ...

随机推荐

  1. C# 函数 递归

    函数:独立完成某项功能的一个个体,有固定功能函数有 高度抽象函数. 作用: 提高代码的重用性 提高功能开发的效率 提高程序代码的可维护性 函数四要素:   输入       输出       函数名  ...

  2. linux系统编程:进程控制(fork)

    在linux中,用fork来创建一个子进程,该函数有如下特点: 1)执行一次,返回2次,它在父进程中的返回值是子进程的 PID,在子进程中的返回值是 0.子进程想要获得父进程的 PID 需要调用 ge ...

  3. 背景平铺(兼容IE8)

    标准浏览器通过background-size属性设置;IE8以下通过滤镜实现. 代码如下: /* IE8 */ filter: progid:DXImageTransform.Microsoft.Al ...

  4. js-数字、字符串、布尔值的转换方式

    来自JavaScript秘密花园 1.转换为字符串 '' + 10 === '10'; // true 将一个值加上空字符串可以轻松转换为字符串类型. 2.字符串转换为数字 +'010' === 10 ...

  5. HTML5+CSS (简易nav设计)

    HTML部分: <!DOCTYPE html><html> <head> <title></title> <meta charset= ...

  6. 在ASP.NET MVC 中使用ActiveReports报表控件

    随着MVC模式的广泛运用,对Web应用系统的开发带来了巨大的影响,我们好像又回到了原来的ASP时代,视乎这是一种后退而不是一种进步,不过MVC模式给我们带来的影响不仅限于我们所看到的这一点..MVC看 ...

  7. springboot 1.3.5升级1.5.9后 默认使用tomcat 8.5版本 get请求报400 异常信息为 The valid characters are defined in RFC 7230 and RFC 3986

    1.springboot 1.3.5升级1.5.9后 默认使用tomcat 8.5版本而之前用的是tomcat7    get请求报400 异常信息为 The valid characters are ...

  8. 【Python】pydot安装失败解决方法

    使用keras时输出网络结构需要用到pydot,总是安装失败,最后按照下面这样的步骤成功了. 1.安装graphviz:pip install graphviz 2.安装graphviz软件,地址在: ...

  9. SQLSERVER中的元数据锁

    SQLSERVER中的元数据锁 网上对于元数据锁的资料真的非常少 元数据锁一般会出现在DDL语句里 下面列出数据库引擎可以锁定的资源 资源 说明 RID 用于锁定堆(heap)中的某一行 KEY 用于 ...

  10. c# 通过GroupBy 进行分组

    有时候我们需要数据根据一些字段进行分组,这时候用orderBy很方便.不多说了.直接上代码: class Ma { public int number { get; set; } public str ...