(A) the definition of
This class provides thread-local variables.
Thread local variables, thread unique variable scope for the current thread
(B) the use of scenarios
(1) target variables related only to the current thread, each thread needs to have a backup of the value
(2) the target variable used several times in the course of the thread execution, resulting in the need to be passed as a parameter in each method used, ThreadLocal provide a thread taken from the current variable approach
(C) Case
Official Case (1) Java documentation available - thread unique identifier
Providing ThreadId class id for each thread, used to identify the thread, the identifier acquired by ThreadId.get () method
You can lookup the id corresponding to the identifier according to the current thread taken by using ThreadLocal, program
public class ThreadId { // Atomic integer containing the next thread ID to be assigned private static final AtomicInteger nextId = new AtomicInteger(0); // Thread local variable containing each thread's ID private static final ThreadLocal<Integer> threadId = new ThreadLocal<Integer>() { @Override protected Integer initialValue() { return nextId.getAndIncrement(); } }; // Returns the current thread's unique ID, assigning it if necessary public static int get() { return threadId.get(); } }
(2) fastjson bytes allocated space - JSON.bytesLocal
In this case, this variable only play a role in JSON bytes allocated space, but unlike the first case when multiple places used to obtain the variable from thread
ThreadLocal used here because each thread is allocated space may not be the same, so each thread should have its own byte space, have their own backup
private final static ThreadLocal<byte[]> bytesLocal = new ThreadLocal<byte[]>(); private static byte[] allocateBytes(int length) { byte[] chars = bytesLocal.get(); if (chars == null) { if (length <= 1024 * 64) { chars = new byte[1024 * 64]; bytesLocal.set(chars); } else { chars = new byte[length]; } } else if (chars.length < length) { chars = new byte[length]; } return chars; }
(3) cat log tags
Use the cat needs to pass a map when playing logging parameters for the trace log, use the following, the third parameter is a map
logger.info(GlobalContext.getLogTitle(), String.format("调用接口,request:%s", SerializationUtils.serialize(request)), GlobalContext.getLogtags());
3.1 For each request is handled by a take threads, each received request is different, so the incoming playing log map is not the same, which is in line with the first scene of ThreadLocal - variable value is only related with the current thread, with respect to the variable each thread has its own backup
3.2 processing a web request to multiple places to play log, if this map are passed in each method parameter in the words will seem very complicated, which is in line with ThreadLocal second scenario - variables need to be used more than once in the course of the execution of thread
One idea is to use a public static class to store and extract the map, but the map is, the value of each thread is not the same at every request, so we use ThreadLocal to store, each thread has its own backup map, through public classes to store and access
public final class GlobalContext { private static final ThreadLocal<Map<String, String>> localLogTags = ThreadLocal.withInitial(HashMap::new); private GlobalContext() {} public static Map<String, String> getLocalLogTags() { return localLogTags.get(); } public static void setLocalLogTags(Map<String, String> logTags) { localLogTags.set(logTags); } public static void addLogTags(String tagName, String tagValue) { localLogTags.get().put(tagName, tagValue); } }
(D) the principle of