文档章节

聊聊TheadLocal

s
 secyaher
发布于 2014/06/06 00:28
字数 674
阅读 12
收藏 0

  TheadLocal 中文叫做线程局部变量,它为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。

  其实主要想讲的是它的数据库连接方面的作用,就是保证一个线程一个事务一个session。由于请求中的一个事务涉及多个 DAO 操作,而这些 DAO 中的 Connection 
不能从连接池中获得,如果是从连接池获得的话,两个 DAO 就用到了两个Connection,这样的话是没有办法完成一个事务的。DAO 中的 Connection 如果是从 ThreadLocal 中获得 Connection 的话那么这些 DAO 就会被纳入到同一个 Connection 之下。当然了,这样的话,DAO 中就不能把 Connection 给关了,关掉的话,下一个使用者就不能用了。

public class DataSourceFactory{
    private static DataSource ds = null;

    private static final ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();

    /**
     * 使用JNDI方式获得数据库源
     * 需要在tomcat/conf/context.xml中配置数据源,如下:
     * <Resource name="jdbc/forceviewDB" type="javax.sql.DataSource" username="forceview" password="forceview" 
        url="jdbc:postgresql://localhost/forceview?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf-8" 
        driverClassName="org.postgresql.Driver" maxIdle="3" maxWait="-1" maxActive="50" 
        validationQuery="select 1" 
        testOnBorrow="true" 
        testOnReturn="true" 
        testWhileIdle="true" 
        removeAbandoned="true" 
        removeAbandonedTimeout="180" 
        logAbandoned="true" 
        timeBetweenEvictionRunsMillis="180000" 
        minEvictableIdleTimeMillis = "180000"
        />
     *注意相关jar包的引入
     * @param jndi
     */
    public static void init(String jndi) {
        if(jndi==null||"".equals(jndi)){
            jndi="java:/comp/env/jdbc/forceviewDB";
        }
        try {
            Context initContext = new InitialContext();
            ds = (DataSource) initContext.lookup(jndi);
        } catch (Exception e) {
            DhccLogger.error("", e);

        }
    }
    /**
     * 使用从spring的ApplicationContext对象中得到的数据源给ds赋值
     * @param ctx
     */
    public static void init(ApplicationContext ctx) {
        try {
            ds = (DataSource) ctx.getBean("dataSource");
        } catch (RuntimeException e) {
            DhccLogger.error("", e);
        }
    }
    /**
     * 使用数据库源给ds赋值
     * @param dataSource
     */
    public static void init(DataSource dataSource) {
        ds=dataSource;
    }

    /**
     * 获取数据库连接
     * 如果threadLocal中没有连接,或者其中的连接已经关闭,
     * 则从数据库连接池中获得,并保存于threadLocal中
     * @return
     */
    public static Connection getConnection() {
        Connection conn = threadLocal.get();

        try {
            if (conn == null || conn.isClosed()) {
                conn = ds.getConnection();
                threadLocal.set(conn);
            }
        } catch (Exception e) {
            DhccLogger.error("", e);
        }
        return conn;
    }

    /**
     * 关闭数据库连接
     * 此方法不进行任何操作,在操作数据库时,习惯最后关闭数据库连接,
     * 应用此类取得的数据库连接最好不要立即关闭,为了习惯,可以使用此方法来代替connection.close()方法
     */
    public static void closeConnection() {
    }

    /**
     * 关闭数据库连接,把数据库连接归还连接池,
     * 此连接对应于连接池中的连接并没有真正关闭,仍由连接池维护
     */
    public static void close() {
        Connection conn = (Connection) threadLocal.get();
        threadLocal.set(null);
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                DhccLogger.error("", e);
            }
        }
    }
}

 

© 著作权归作者所有

s
粉丝 2
博文 467
码字总数 423946
作品 0
私信 提问
ThreadLocal的细节和设计模式

提要: 1.都知道ThreadLocal都是线程局部变量,可以比作是个Thread->T的MAP,那么有个问题了,如果一个类维护了一个TL的局部变量,随着不同的线程访问,这个TL会变得很大么?我们需要在线程结...

天天顺利
2015/09/18
57
0
Java TheadLocal

原文链接 作者:Jakob Jenkov 查看全部文章 Java中的ThreadLocal类可以让你创建的变量只被同一个线程进行读和写操作。因此,尽管有两个线程同时执行一段相同的代码,而且这段代码又有一个指向...

暗之幻影
2016/12/19
11
0
Java并发库(Java Concurrency)

原文地址 译文地址 译者:张坤等 Java并发性和多线程介绍(Java Concurrency / Multithreading Tutorial) 多线程的优点(Multithreading Benefits) 多线程的代价(Multithreading Costs) ...

暗之幻影
2016/12/17
103
0
SimpleDateFormat线程不安全示例及其解决方法

我们可以用java.text.SimpleDateFormat类完成日期的转换和格式化操作,如: 但是,同时,我们也能从java.text.SimpleDateFormat类的javadoc中看到如下一句话。 Date formats没有同步。 建议为...

王孟君
2016/11/20
265
0
聊聊并发系列_Index

聊聊并发系列 聊聊并发(一)深入分析Volatile的实现原理 聊聊并发(二)Java SE1.6中的Synchronized 聊聊并发(三)Java线程池的分析和使用 聊聊并发(四)深入分析ConcurrentHashMap 聊聊并...

陶邦仁
2016/01/04
652
0

没有更多内容

加载失败,请刷新页面

加载更多

实战项目-学成在线(一)

之前看的黑马程序员实战项目之一,打算以博客的形式写出来,也让自己重新温习一下。 1、项目背景 略(就是当前这东西很火,我们重点在开发,这些就略过) 2、功能模块 门户,学习中心,教学管...

lianbang_W
34分钟前
4
0
基于Vue的数字输入框组件开发

本文转载于:专业的前端网站➫基于Vue的数字输入框组件开发 1、概述 Vue组件开发的API:props、events和slots 2、组件代码 github地址:https://github.com/MengFangui/VueInputNumber 效果:...

前端老手
42分钟前
4
0
百度地图根据经纬度获取运动轨迹

<!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="initial-scale=1.0, user-scalable=n......

泉天下
44分钟前
5
0
学习记录(day04-axios增删改查、v-for循环、页面加载成功处理函数)

[TOC] 1.1 基本语法:插值表达式 <template> <div> {{username}} <br/> {{1+2+3}} <br/> {{'你的名字是:' + username}} <br/> {{'abc'.split('')}} </div><......

庭前云落
今天
5
0
CentOS Linux 7上将ISO映像文件写成可启动U盘

如今,电脑基本上都支持U盘启动,所以,可以将ISO文件写到U盘上,用来启动并安装操作系统。 我想将一个CentOS Linux 7的ISO映像文件写到U盘上,在CentOS Linux 7操作系统上,执行如下命令: ...

大别阿郎
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部