问题是这样的:项目中是用ThreadContext这个类来存上下文Context,我们发现从TheadContext里面拿出来的Context有一定几率会串掉。例如开两个浏览器一个用admin登陆,另一个用的是demoUser登陆,结果是admin的登陆的用户操作后有一定几率会log成demoUser.ThreadContext代码如下,大牛们帮我看下这个类是不是有问题,或是有怎样的可能会导致这样的问题。public class ThreadContext
{
    private static ThreadLocal current = new InheritableThreadLocal();
    public static HashMap getContext()
    {
        if (current.get() == null) {
            createContext(); // Create a new one...
        }
//        System.out.println("==========getContext=========="+Thread.currentThread().hashCode());
        return (HashMap) current.get();
    }    public static void createNewContext(){
        createContext(); // Create a new one...
    } /** returns the client context set in the thread local */
public static IClientContext getClientContext()
{
return (IClientContext) ThreadContext.getContext().get("CLIENT_CONTEXT");
}    /** Set client context in Thread Local */
    public static void setClientContext(IClientContext ctx) {
        ThreadContext.getContext().put("CLIENT_CONTEXT", ctx);
        System.out.println("======Thread Name============"+Thread.currentThread().hashCode()+"===UseName=="+ctx.getUsername());
    }
    private static void createContext()
    {
    current.set(new HashMap());
    }
}

解决方案 »

  1.   

    private static ThreadLocal current = new InheritableThreadLocal();加static修饰符寓意何在
      

  2.   

    ThreadLocal是跟线程绑定在一块的,服务器一般都是使用线程池,也就是说,并不是每一个用户都对应一个全新的线程,后登陆的用户可能还是使用的前一个用户的线程,如果前一个用户已经退出的话,此时后登陆的用户就可以获取到前一个用户设置在ThreadLocal里面的数据。解决办法是:
    使用一个ServletRequestListener,在requestInitialized()里面往ThreadLocal里面放数据,在requestDestroyed()里面清除数据。这样就不会乱了。
      

  3.   

    ThreadLocal 确实是能解决线程间临界区的问题,但如果是对于同一条线程呢?一样会覆盖之前的值吧,先判断下是不是同一条线程操作吧
      

  4.   

    我也怀疑过是两个用户用了同一个线程导致了context串掉了的问题,所以打印了Thread.currentThread().hashCode()。但是结果却是admin的线程和demouser的不一样。很疑惑。extact.java部分代码:            System.out.println("========@@@@@@@@@@@========="+Thread.currentThread().hashCode());
                IClientContext hContext1 = ThreadContext.getClientContext();
                System.out.println("========@@@@@@@@@@@========="+Thread.currentThread().hashCode());
    ThreadContext.java加个log代码:
      public static void setClientContext(IClientContext ctx) {
      ThreadContext.getContext().put("CLIENT_CONTEXT", ctx);
      System.out.println("======Thread Name============"+Thread.currentThread().hashCode()+"===UseName=="+ctx.getUsername());
      }log如下
    11/12/28 07:06:40 ======Thread Name============17944285===UseName==admin
    11/12/28 07:06:40 ======Thread Name============17944285===UseName==admin
    11/12/28 07:06:40 ======Thread Name============17944285===UseName==admin
    11/12/28 07:06:41 ======Thread Name============3702564===UseName==demouser
    11/12/28 07:06:41 ======Thread Name============3702564===UseName==demouser
    11/12/28 07:06:41 ======Thread Name============3702564===UseName==demouser
    11/12/28 07:06:41 ======Thread Name============3702564===UseName==demouser
    11/12/28 07:06:45 ======Thread Name============19088854===UseName==demouser
    11/12/28 07:06:45 ======Thread Name============19088854===UseName==demouser
    11/12/28 07:06:45 ======Thread Name============19088854===UseName==demouser
    11/12/28 07:06:45 ======Thread Name============19088854===UseName==demouser
    11/12/28 07:06:47 ========@@@@@@@@@@@=========17944285
    11/12/28 07:06:47========call ThreadContext.getClientContext()=====Context user is demouser
    11/12/28 07:06:47 ========@@@@@@@@@@@=========17944285
      

  5.   


    我也怀疑过是两个用户用了同一个线程导致了context串掉了的问题,所以打印了Thread.currentThread().hashCode()。但是结果却是admin的线程和demouser的不一样。很疑惑。extact.java部分代码: System.out.println("========@@@@@@@@@@@========="+Thread.currentThread().hashCode());
      IClientContext hContext1 = ThreadContext.getClientContext();
      System.out.println("========@@@@@@@@@@@========="+Thread.currentThread().hashCode());
    ThreadContext.java加个log代码:
      public static void setClientContext(IClientContext ctx) {
      ThreadContext.getContext().put("CLIENT_CONTEXT", ctx);
      System.out.println("======Thread Name============"+Thread.currentThread().hashCode()+"===UseName=="+ctx.getUsername());
      }log如下
    11/12/28 07:06:40 ======Thread Name============17944285===UseName==admin
    11/12/28 07:06:40 ======Thread Name============17944285===UseName==admin
    11/12/28 07:06:40 ======Thread Name============17944285===UseName==admin
    11/12/28 07:06:41 ======Thread Name============3702564===UseName==demouser
    11/12/28 07:06:41 ======Thread Name============3702564===UseName==demouser
    11/12/28 07:06:41 ======Thread Name============3702564===UseName==demouser
    11/12/28 07:06:41 ======Thread Name============3702564===UseName==demouser
    11/12/28 07:06:45 ======Thread Name============19088854===UseName==demouser
    11/12/28 07:06:45 ======Thread Name============19088854===UseName==demouser
    11/12/28 07:06:45 ======Thread Name============19088854===UseName==demouser
    11/12/28 07:06:45 ======Thread Name============19088854===UseName==demouser
    11/12/28 07:06:47 ========@@@@@@@@@@@=========17944285
    11/12/28 07:06:47========call ThreadContext.getClientContext()=====Context user is demouser
    11/12/28 07:06:47 ========@@@@@@@@@@@=========17944285