Questions about using ThreadLocal in <single> w760> Support

In my one-window service class below, all methods in the class require some user context that is known to be called Service.doA(). Instead of passing information through methods, I thought about storing these values ​​in TheadLocal. I have two questions about this approach:

1) Is the implementation used correctly ThreadLocal? That is, it is thread safe, and the correct values ​​will be read / written to ThreadLocal?

2) Is it necessary to clear ThreadLocal userInfoexplicitly to prevent memory leak? Will there be garbage collection?

@Service
public class Service {
    private static final ThreadLocal<UserInfo> userInfo = new ThreadLocal<>(); 

    public void doA() {
        // finds user info
        userInfo.set(new UserInfo(userId, name));
        doB();
        doC();
    }

    private void doB() {
        // needs user info
        UserInfo userInfo = userInfo.get();
    }

    private void doC() {
        // needs user info
        UserInfo userInfo = userInfo.get();
    }
}
+4
3

1) , doB doC, , ThreadLocal, , , ThreadLocal.

2) , ThreadLocal, . , , , . ThreadLocal, , , . GC, threadlocal , . API doc:

, , ThreadLocal ; , , ​​ - ( ).

, , ThreadLocal. ThreadLocal , , , , . , , AOP , threadlocal .

, , , , -, threadlocal , threadpool. try-finally, , threadlocal, , .

+5

ThreadLocal, , , , :

  • - , GC, GC , , . , , ThreadLocal , ThreadLocalMap, - ThreadLocalMap#remove(), ThreadLocalMap. GC , ThreadLocal GC, Service, GC, , . - ThreadLocalMap#remove().
  • , , , ThreadLocal, thread pool, , , ThreadLocal , ThreadLocal, , . , , , , ThreadLocal .

, :

try {
    userInfo.set(new UserInfo(userId, name));
    // Some code here 
} finally {
    // Clean up your thread local whatever happens
    userInfo.remove();
}

, , , UserInfo , UserInfo, UserInfo, ThreadLocal, , ThreadLocal - .

+1

It should definitely be cleaned after use. ThreadLocals memory leaks are extremely easy, both heap memory and permgen / metaspace memory through class heaters. In your case, the best way is:

public void doA() {
  // finds user info
  userInfo.set(new UserInfo(userId, name));
  try {
    doB();
    doC();
  } finally {
    userInfo.remove()
  }
}
0
source

All Articles