前置觀念 - 必須了解Thread, Thread.currentThread()被呼叫的機制, call stack機制.
ThreadLocal的目的 : 把變數存在currentThread中, 讓每個執行中的Thread都有自己的一份Copy, 而且彼此之間不會互相影響.
實作概念 :
public class ThreadLocalConcept{
private Map<Thread,Object> localMap = Collections.synchronizedMap(new HashMap<Thread,Object>());
public void set(Object obj){
this.localMap.put(Thread.currentThread(), obj);
}
public Object get(){
this.localMap.get(Thread.currentThread());
}
}
基本上就是這個localMap會放著各個Thread對應的變數, 因此在不同的Thread中呼叫到的Value都會是獨立的.
用途範例 : 在DAO中拿到Login User
一般來說Login User都是放在Session中, 但是平常我們使用的Service & DAO都會是Singleton, 是共用的, 因此不能夠將Login User放入
我們可以利用一個Request-Response是一個獨立Thread的特性, 搭配ThreadLocal將Login User存入各個Thread中,就可以拿到相對應的Login User了
Step1. 建立一個共用的Thread Local
public class LoginUserUtil{
public static ThreadLocal<User> local = new ThreadLocal<User>();
public static User getUser(){
return local.get();
}
public static void setUser(User user){
local.set(user);
}
}
step2. 在BaseAction/BaseServlet/BaseController內放入LoginUser
public class BaseAction extends ...{
public doBaseRequest(){
User user = this.getRequest().getSession().getAttribute("loginUser");
LoginUserUtil.set(user);
}
}
step3. 在DAO中拿出LoginUser - 完工!!
public class XXXDAOImpl extends ...{
public void updateData(Data data){
data.setUpdateUser(LoginUserUtil.get());
this.update(data);
}
}
留言列表