ThreadLocal使用

#ThreadLocal使用

##Thread介绍

###1、set方法

1
2
3
4
5
6
7
8
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}

每个线程里面居然都有一个threadlocals变量,是ThreadLocalMap的引用,set方法就是往里面设置值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void set(ThreadLocal<?> key, Object value) {
Entry[] tab = table; //table
int len = tab.length; //tab的长度
int i = key.threadLocalHashCode & (len-1); //当前ThreadLocal hashkode且长度
for (Entry e = tab[i]; e != null;
e = tab[i = nextIndex(i, len)]) {
ThreadLocal<?> k = e.get(); //从table数组中拿到
if (k == key) {
e.value = value; //当前value设置给entry里面的,替换掉原值
return;
}
if (k == null) { //当前entry为空
replaceStaleEntry(key, value, i); //当前key设置进来
return;
}
}
tab[i] = new Entry(key, value);//table为空,就直接new一个
int sz = ++size;
if (!cleanSomeSlots(i, sz) && sz >= threshold)
rehash(); //如果长度大于threshold(阈值),重新hash
}

  • One possible (and common) use is when you have some object that is not thread-safe, but you want to avoid synchronizing access to that object (I’m looking at you, SimpleDateFormat). Instead, give each thread its own instance of the object.
    For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Foo
{
// SimpleDateFormat is not thread-safe, so give one to each thread
private static final ThreadLocal<SimpleDateFormat> formatter = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyyMMdd HHmm");
}
};
public String formatIt(Date date)
{
return formatter.get().format(date);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
//added by jude end 手续费 扣平台手续费,用户不扣手续费
//平台收取用户5%的手续费,先打给平台,然后平台垫付
//充值手续费
$chongzhi_fee_rate_plat = Core::$recharge_fee;
$chongzhi_fee_plat = round($payAmount / (1 + $chongzhi_fee_rate_plat) * $chongzhi_fee_rate_plat, 2);
if ($chongzhi_fee_plat < 0.01)
$chongzhi_fee_plat = 0.01;
$this->FinanceAccount->accountOpByAlias("chongzhi_fee_baofoo", $chongzhi_fee_plat, "user:{$m_id}", "site_baofoo",$remark);
$this->FinanceAccount->accountOpByAlias("chongzhi_fee_out_baofoo", $payAmount*0.001, "site_baofoo", "site_baofoo_out",$remark);//这里的0.01不能改
//因为实际不收取手续费,所以还给用户,只是有资金记录
$this->FinanceAccount->accountOpByAlias("site_activity", $chongzhi_fee_plat, "sitebalance", "user:{$m_id}", Core::$DeductFeePrompt);
Share