ThreadLocal

来源:互联网 发布:mac锁屏快捷键 编辑:程序博客网 时间:2024/06/07 02:55

当访问共享的可变数据时,通常需要使用同步。

一种避免使用同步的方式就是不共享数据。如果尽在单线程内访问数据,就不需要同步。这种技术被称为线程封闭,这是实现线程安全最简单的方式之一。

ThreadLocal是一种维持线程封闭性的方法。

ThreadLocal类能使线程中的某个值域保存值的对象关联起来。

ThreadLocal提供的get和set等方法,为每个使用该变量的线程都存有一份独立的副本,因此get总是返回有当前执行线程在调用set时设置的最新值。

ThreadLoca对象通常用于全局变量的共享,例如用于jdbc线程池

import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;public class DataSourceUtils {private static DataSource dataSource = new ComboPooledDataSource();private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();// 直接可以获取一个连接池public static DataSource getDataSource() {return dataSource;}//从当前线程城绑定中获得connnectionpublic static Connection getCurrentConnection() throws SQLException{Connection conn = tl.get(); //判断ThreadLocal中是否已经有connecctionif(conn==null){conn = getConnection();tl.set(conn);}return conn;}// 获取连接对象public static Connection getConnection() throws SQLException {return dataSource.getConnection();}public static void startTransaction() throws SQLException {Connection conn = getCurrentConnection();conn.setAutoCommit(false);}public static void rollback() throws SQLException {Connection conn = getCurrentConnection();conn.rollback();}public static void commit() throws SQLException {Connection conn = getCurrentConnection();conn.commit();tl.remove();conn = null;}}

上例的DataSourceUtils的getCurrentConnection就使用了ThreadLocal类来保证当前线程得到的是同一个DataSource,

这可以用于jdbc连接保证service层的事务。

例如在service层开启事务,并执行业务逻辑,如果成功就commit,如果失败就rollback。可是如果在service层和dao层使用的连接不是同一个connection。则不能保证事务的一致性。

而ThreadLocal则可以避免这种情况的发生,在service层开启事务,并执行业务逻辑,如果成功就commit,如果失败就rollback。而在dao层使用getCurrentConnection获取的就是service层使用的connection,这样就保证了connection的唯一。

原创粉丝点击