最近在学习drp的时候,涉及到了线程安全的问题,看视频中用到了ThreadLocal,所以看了一些资料将这块的知识来个小小的总结,若有不当之处,很欢迎大家替我指出,不胜感激。
在drp中的ThreadLocal的应用是将数据库库的连接变量分享到了各个线程中,使得各个线程隔离使用数据库连接变量,从而实现线程安全。
ThreadLocal中最重要的3个方法:
1.Get方法获得当前线程变量
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e =map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
2.set方法是将当前线程设置到线程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);
}
3.remove方法是移除当前线程变量
public void remove() {
ThreadLocalMap m =getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
实战片段:
public classConnectionManager {
//实例化ThreadLocal对象
private static ThreadLocal<Connection> connectionHolder=new ThreadLocal<Connection>();
public static Connection getConnection(){
//获得当前的线程连接变量
Connection conn= connectionHolder.get();
if(conn==null){
try {
JdbcConfig jdbcConfig = XmlConfigReader.getInstance().getJdbcConfig();
//初始化驱动包 Class.forName(jdbcConfig.getDriverName());
conn=DriverManager.getConnection(jdbcConfig.getUrl(),jdbcConfig.getUserName(),jdbcConfig.getPassword());
//将当前的线程连接变量设置到ThreadLocal中
connectionHolder.set(conn);
}catch(ClassNotFoundException e){
e.printStackTrace();
thrownew ApplicationException("系统错误,请联系系统管理员");
} catch (Exceptione) {
// TODO:handle exception
e.printStackTrace();
throw newApplicationException("系统错误,请联系系统管理员");
}
}
return conn;
}
//关闭线程连接
public static void closeConnection(){
Connection cnn= connectionHolder.get();
if(cnn!=null){
try {
cnn.close();
connectionHolder.remove();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
小结:之前一直听各种关于线程安全方面的知识,但是真正的实施很少。无论是之前的为了事务安全的加锁机制,还是现在的多线程之间的数据传递问题,都是我需要在今后的项目中不断实战累加经验的,而我也相信practice makes perfect。