ThreadLocal的使用非常简单
ThreadLocal user = new ThreadLoca();
user.set("username", "jackliu");
String username = user.get("username");

ThreadLocal是维护线程本地变量的一个很好的方法
只有本线程才能获得本线程内设置的变量,其他线程无法获取

 /**
     * Returns the value in the current thread's copy of this thread-local
     * variable.  Creates and initializes the copy if this is the first time
     * the thread has called this method.
     *
     * @return the current thread's value of this thread-local
     */
    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            return (T)map.get(this);

        // Maps are constructed lazily.  if the map for this thread
        // doesn't exist, create it, with this ThreadLocal and its
        // initial value as its only entry.
        T value = initialValue(); //return null
        createMap(t, value);
        return value;
    }

    /**
     * Sets the current thread's copy of this thread-local variable
     * to the specified value.  Many applications will have no need for
     * this functionality, relying solely on the {@link #initialValue}
     * method to set the values of thread-locals.
     *
     * @param value the value to be stored in the current threads' copy of
     *        this thread-local.
     */
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

    /**
     * Removes the value for this ThreadLocal.  This may help reduce
     * the storage requirements of ThreadLocals.  If this ThreadLocal
     * is accessed again, it will by default have its
     * <tt>initialValue</tt>.
     * @since 1.5
     **/

     public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }

    /**
     * Get the map associated with a ThreadLocal. Overridden in
     * InheritableThreadLocal.
     *
     * @param  t the current thread
     * @return the map
     */
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

    /**
     * Create the map associated with a ThreadLocal. Overridden in
     * InheritableThreadLocal.
     *
     * @param t the current thread
     * @param firstValue value for the initial entry of the map
     * @param map the map to store.
     */
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

前段时间有个需求就将是需要一个全局点去获取登陆用户的用户名。
这个需求看起来很简单,但是却没有合适的办法。
因为如果需要session变量,那么必须在servlet的处理类中,但是很多类并不是servlet
而且也得不到request变量,所以在普通内里面没有办法获取到登陆用户名
这个时候就需要使用到ThreadLocal类
于是写了一个Filter。要注意的是因为web服务器针对每个web请求都会启动一个Thread
所以,每次都需要调用UserUtil.setUserName方法才能保证每个线程都能得到正确的用户名。


import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.ofbiz.base.util.Debug;
import org.ofbiz.entity.GenericValue;

import com.aicent.ccb.util.StringUtils;
import com.aicent.ccb.util.UserUtil;

public class UserLogFilter implements Filter {
 public static final String module = UserLogFilter.class.getName();

 public void destroy() {

 }

 public void doFilter(ServletRequest request, ServletResponse response,
   FilterChain chain) throws IOException, ServletException {

  HttpServletRequest httpRequest = (HttpServletRequest) request;

  String USERNAME = httpRequest.getParameter("USERNAME");

  if (StringUtils.isValid(USERNAME)) {
   UserUtil.setUserName(USERNAME);
   Debug.logInfo("in request set user name=" + UserUtil.getUserName(),
     module);
  } else {
   HttpSession session = httpRequest.getSession();
   if (null != session) {

    GenericValue userLogin = (GenericValue) session
      .getAttribute("userLogin");
    if (userLogin != null) {
     UserUtil.setUserName(userLogin.getString("userLoginId"));
     Debug.logInfo(
       "in session set user name=" + UserUtil.getUserName(),
       module);
    }
   } else {
    Debug.logInfo("No user in the session", module);
   }
  }

  chain.doFilter(request, response);
 }

 public void init(FilterConfig fc) throws ServletException {

 }

}


public class UserUtil {
  private static final ThreadLocal user = new ThreadLocal() {
         public Object initialValue() {
             return "Unknown User";
         }
     };
  public static void setUserName(String userName){
   user.set(userName);
  }
 
  public static String getUserName(){
   return (String)user.get();
  }
}