ThreadLocal的作用与使用

在我们编程时,如果遇到多个线程访问同一个变量应该怎样实现?有人说使用同步。是的同步可以解决这种问题,但它是有弊端的,涉及到何时加锁与释放锁等并且线程访问锁时需要等待,这样很浪费时间。有一个更好的方案就是使用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);
			}
		}
	}

这样多线程在访问数据源时,就可以做到互不干扰。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值