ThreadLocal<T> 变量含义(线程局部变量)JDK1.5以后支持泛型

ThreadLocal用处:保存线程的独立变量。对一个线程类(继承自Thread)
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。常用于用户登录控制,如记录session信息。

实现:每个Thread都持有一个TreadLocalMap类型的变量(该类是一个轻量级的Map,功能与map一样,区别是桶里放的是entry而不是entry的链表。功能还是一个map。)以本身为key,以目标为value。
主要方法是get()和set(T a),set之后在map里维护一个threadLocal -> a,get时将a返回。ThreadLocal是一个特殊的容器。

 

package Thread;

public class ThreadLocalTest {
	static class ResourceClass {

		public final static ThreadLocal<String> RESOURCE_1 =
									   new ThreadLocal<String>();

		public final static ThreadLocal<String> RESOURCE_2 =
									   new ThreadLocal<String>();

	}

	static class A {

		public void setOne(String value) {
			ResourceClass.RESOURCE_1.set(value);
		}

		public void setTwo(String value) {
			ResourceClass.RESOURCE_2.set(value);
		}
	}

	static class B {
		public void display() {
			System.out.println(ResourceClass.RESOURCE_1.get()
						+ ":" + ResourceClass.RESOURCE_2.get());
		}
	}

	public static void main(String []args) {
		final A a = new A();
		final B b = new B();
		for(int i = 0 ; i < 15 ; i ++) {
			final String resouce1 = "线程-" + i;
			final String resouce2 = " value = (" + i + ")";
			new Thread() {
				public void run() {
				try {
					a.setOne(resouce1);
					a.setTwo(resouce2);
					b.display();
				}finally {
					ResourceClass.RESOURCE_1.remove();
					ResourceClass.RESOURCE_2.remove();
				}
			}
		}.start();
		}
	}
}

 输出结果为:

线程-0: value = (0)
线程-3: value = (3)
线程-2: value = (2)
线程-4: value = (4)
线程-1: value = (1)
线程-6: value = (6)
线程-5: value = (5)
线程-7: value = (7)
线程-8: value = (8)
线程-9: value = (9)
线程-10: value = (10)
线程-12: value = (12)
线程-13: value = (13)
线程-14: value = (14)
线程-11: value = (11)

 

       ThreadLocal为每一个线程提供一个独立的变量副本,从而隔离了多个线程对访问数据的冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的对象封装,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。 

  jfina框架对此ThreadLocal使用较多一些,很好的解决方案,这里摘录一段Javen的开源ijpay源码,详情请大家去开源网站去阅读了解;jfina框架也特别优秀。

package com.jpay.alipay;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.jpay.ext.kit.StrKit;

public class AliPayApiConfigKit {
	private static final ThreadLocal<String> TL = new ThreadLocal<String>();
	
	private static final Map<String, AliPayApiConfig> CFG_MAP = new ConcurrentHashMap<String, AliPayApiConfig>();
	private static final String DEFAULT_CFG_KEY = "_default_ijpay_key_";
	
	/**
	 * 添加支付宝支付配置,每个appId只需添加一次,相同appId将被覆盖
	 * @param aliPayApiConfig 支付宝支付配置
	 * @return {AliPayApiConfig} 支付宝支付配置
	 */
	public static AliPayApiConfig putApiConfig(AliPayApiConfig aliPayApiConfig) {
        if (CFG_MAP.size() == 0) {
        	CFG_MAP.put(DEFAULT_CFG_KEY, aliPayApiConfig);
        }
        return CFG_MAP.put(aliPayApiConfig.getAppId(), aliPayApiConfig);
    }
	
	public static AliPayApiConfig setThreadLocalAliPayApiConfig(AliPayApiConfig aliPayApiConfig) {
        return putApiConfig(aliPayApiConfig);
    }

    public static AliPayApiConfig removeApiConfig(AliPayApiConfig apiConfig) {
        return removeApiConfig(apiConfig.getAppId());
    }

    public static AliPayApiConfig removeApiConfig(String appId) {
        return CFG_MAP.remove(appId);
    }

    public static void setThreadLocalAppId(String appId) {
        if (StrKit.isBlank(appId)) {
            appId = CFG_MAP.get(DEFAULT_CFG_KEY).getAppId();
        }
        TL.set(appId);
    }

    public static void removeThreadLocalAppId() {
        TL.remove();
    }
	
    public static String getAppId() {
        String appId = TL.get();
        if (StrKit.isBlank(appId)) {
            appId = CFG_MAP.get(DEFAULT_CFG_KEY).getAppId();
        }
        return appId;
    }

    public static AliPayApiConfig getAliPayApiConfig() {
        String appId = getAppId();
        return getApiConfig(appId);
    }

    public static AliPayApiConfig getApiConfig(String appId) {
    	AliPayApiConfig cfg = CFG_MAP.get(appId);
        if (cfg == null)
            throw new IllegalStateException("需事先调用 AliPayApiConfigKit.putApiConfig(aliPayApiConfig) 将 appId对应的 aliPayApiConfig 对象存入," +
                    "才可以使用 AliPayApiConfigKit.getAliPayApiConfig() 的系列方法");
        return cfg;
    }
}

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值