您的位置:首页 > 其它

ThreadLocal的作用与使用

2017-01-13 10:40 246 查看
在我们编程时,如果遇到多个线程访问同一个变量应该怎样实现?有人说使用同步。是的同步可以解决这种问题,但它是有弊端的,涉及到何时加锁与释放锁等并且线程访问锁时需要等待,这样很浪费时间。有一个更好的方案就是使用ThreadLocal工具类,之前参加了一个项目,本项目涉及到分库,在业务进行中需要根据唯一的ID去定位数据源然后做一系列的操作。

ThreadLocal不是用来解决共享资源的多线程访问的问题, hreadLocal的set()方法设置到线程的ThreadLocal.ThreadLocalMap里的是线程自己要存储的对象,其他线程访问不到。各个线程中的ThreadLocal.ThreadLocalMap以及ThreadLocal.ThreadLocal中的值都是不同的对象。

下面看一下定位与设置数据源的工具类

/**
* 在ThreadLocal中保存当前线程需要使用的String。
*
* @author wangzuojia
*/
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();

public static void setDataSource(String type) {
// 不使用mycat时这里切换数据源的地方进行屏蔽
contextHolder.set(type);
}

public static String determineCurrentLookupKey() {
String dbtype = (String)contextHolder.get();
return dbtype;
}

public static String getDataSource() {
String dbtype = (String)contextHolder.get();
if(dbtype == null ){
//获取默认数据源
dbtype = getDefaultDataSource();
}
return dbtype;
}

public static String getDefaultDataSource() {
//获取默认数据源
String defaultDbtype = (String) SpringContextHolder.getBean("defaultDbtype");
defaultDbtype = defaultDbtype.trim();

//logger.info("defaultDatasource:"+defaultDbtype);
return defaultDbtype;
}

public static void clearString() {
contextHolder.remove();
}
}

下面看一下如何使用获取数据源的工具类
public static void updateTIdMappingStatus(String id,String tablename,String key1,String key2,String key3,String key4,String oldstatus,String status){
TIdmappingService tIdmappingService = SpringContextHolder.getBean(TIdmappingService.class);

// 获取正在使用的dbtype
String oldDbtype = DataSourceContextHolder.getDataSource();
try {
DataSourceContextHolder.setDataSource(DatasourceSpiltUtil.dbtype_default);
tIdmappingService.updateTIdMappingStatus( id, tablename, key1, key2, null, null, oldstatus, status);
} finally {
// 还原正在使用的dbtype
if (oldDbtype != null) {
DataSourceContextHolder.setDataSource(oldDbtype);
}
}
}

这样多线程在访问数据源时,就可以做到互不干扰。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  多线程 分库