`
bcyy
  • 浏览: 1841999 次
文章分类
社区版块
存档分类
最新评论

ThreadLocal 我所用到的地方

 
阅读更多

92. 现在来看怎么把三个方法保证同步,servlet是单实例多线程运行的,你去调用FlowCardServlet就
会启动一个线程,在这个线程里其实就调用了你写的那三个方法,现在我就只要保证你这三个方法都在一个线程里面就可以了。

93. 在同一个线程里保证使用一个connection这就涉及到一个类ThreadLocal
这个类不是本地线程的意思,这个类就在java.lang包中。作用:你放在这里面的东西,他会在整个线程里共享,在其它线程里不共享。


94. 不用框架要考虑的东西太多了,这样就会造成以后的维护成本提高啊。


95. 你可以这样理解,这个类的底层是 一个map{
key=当前线程变量001,也可以理解为这个是一个唯一标识的东西吧,不好理解,你就这么理解
value = new connection()

key=当前线程变量002
value = new connection() 这两个connection是不一样的,他们是不相互干扰的。
}

在这整个线程中就共享着一个
value对应的就是你具体的东西,你爱放什么就放什么,他接收一个Object参数。


96. ThreadLocal这个很重要,因为现在很多都使用这个东西。
这个类里面就四个方法。
public void set(T value){}你传一个connection进来,他就放到了一个map里面去了。

public void set(T value){
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if(map != null)
map.set(this,value);
else
createMap(t,value);
}别人再调用,他又map.set()设置一个了。如果有10个人设置进去东西了,我怎么就能拿到我的呢?


97. 他还有一个get(T value)方法。
map.get(0001);你当前线程对应的是0001 他就拿0001的东西。


98. 现在再建一个类来封装ThreadLocal
他命名命得好啊,connection的管理
public class ConnectionManager{
private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>();

现在都是在多线程中运行的,你开一个就开一个线程我得看看,在当前线程中绑没绑定一个connection
public static Connection getConnection(){
Connection conn = connectionHolder.get();
用了泛型你不用管了,里面就是coneciton
if(conn == null){ 当前线程没有绑定我就创建
JdbcInfo jdbcInfo = ConfigReader.getInstance().getJdbcInfo();
Class.forName(jdbcInfo.getDriverName());
conn = DriverManager.getConneciton(jdbcInfo.getUrl(),jdbcInfo.getUsername(),jdbcInfo.getPassword());
connectionHolder.set(conn);
}
}
return conn;
}

holder:持有

关闭方法,你想你要关闭,你怎么关,你只能关你自己的connection
public static void closeConnection(){
Connection conn = connectionHolder.get();
if(conn !=null){
conn.close();
conntionHolder.remove();你把他关了,他map里面的东西还存在啊,所以你得移除了。
}
}


99. 这思想就和我在方法中定义的变量只能在这个方法里面使用。


100. 我们还可以采用同步机制来解决线程安全问题

1. connection什么时候关闭,应该是那三个方法全部执行完


2. 这个connection应该是在FlowCardServiceImpl这一层开,在这一层关。

/**
* 采用ThreadLocal封装Connection
* ThreadLocal可以在同一个线程中共享变量
* @author Administrator
*
*/
public class ConnectionManager {

private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>();

/**
* 取得connection
* @return
*/
public static Connection getConnection() {
Connection conn = connectionHolder.get();
//如果在ThreadLocal中不存在与当前线程绑定的Connection
//那么我们就创建一个Connection,并将其放到ThreadLocal中
if (conn == null) {
try {
//取得jdbc配置信息
JdbcInfo jdbcInfo = ConfigReader.getInstance().getJdbcInfo();
Class.forName(jdbcInfo.getDriverName());
conn = DriverManager.getConnection(jdbcInfo.getUrl(), jdbcInfo.getUsername(), jdbcInfo.getPassword());

//放到ThreadLocal中
connectionHolder.set(conn);
} catch (ClassNotFoundException e) {
//记录日志可以将类不能找记录进去,这样可以更准确的定位问题
//但是给用户不应该抛出类不能找到,应该抛出用户能够理解的错误
e.printStackTrace();
throw new AppException("系统出现故障,请联系系统管理员!");
} catch (SQLException e) {
e.printStackTrace();
throw new AppException("系统出现故障,请联系系统管理员!");
}
}
return conn;
}

/**
* 关于connection
*/
public static void closeConnection() {
Connection conn = connectionHolder.get();
if (conn != null) {
try {
conn.close();
//从ThreadLocal中移除
connectionHolder.remove();
} catch (SQLException e) {
e.printStackTrace();
}
}

}

public static void close(PreparedStatement pstmt) {
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

public static void close(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

public static void commit(Connection conn) {
if (conn != null) {
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

public static void rollback(Connection conn) {
if (conn != null) {
try {
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

public static void setAutoCommit(Connection conn, boolean autoCommit) {
if (conn != null) {
try {
conn.setAutoCommit(autoCommit);
} catch (SQLException e) {
e.printStackTrace();
}
}
}

public static void close(Statement stmt) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

转自:http://xiechao240.iteye.com/blog/738480

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics