java in use ThreadLocal

java in use ThreadLocal

ThreadLocal mainly used to store data for the current thread, the current thread can access the data only.

In the definition of ThreadLocal, we can define a specific type of object stored in the ThreadLocal simultaneously.

ThreadLocal<Integer> threadLocalValue = new ThreadLocal<>();
复制代码

Above, we define a storage ThreadLocal objects of Integer.

ThreadLocal to store and retrieve objects is also very simple to use get () and set () to:

threadLocalValue.set(1);
Integer result = threadLocalValue.get();
复制代码

I can ThreadLocal seen as a map, and the current thread is to map the key.

In addition to a new ThreadLocal object, we can also:

    public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {
        return new SuppliedThreadLocal<>(supplier);
    }
复制代码

ThreadLocal static methods provided withInitial to initialize a ThreadLocal.

ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 1);
复制代码

Supplier withInitial requires a target, the initial value acquired by calling the Supplier's get () method.

To delete the data stored in the ThreadLocal, you can call:

threadLocal.remove();
复制代码

Now I by comparing two examples, look at the benefits of using the ThreadLocal.

In practical applications, we often need to request a different store user information for different users, in general, we need to build a global the Map to to store user information different depending on the user ID, to facilitate access to the back .

Storing user data in a Map

If we look at how to use the global use of the Map:

public class SharedMapWithUserContext implements Runnable {

    public static Map<Integer, Context> userContextPerUserId
            = new ConcurrentHashMap<>();
    private Integer userId;
    private UserRepository userRepository = new UserRepository();

    public SharedMapWithUserContext(int i) {
        this.userId=i;
    }

    @Override
    public void run() {
        String userName = userRepository.getUserNameForUserId(userId);
        userContextPerUserId.put(userId, new Context(userName));
    }
}
复制代码

Here we define a static Map to access user information.

Look again at how to use:

    @Test
    public void testWithMap(){
        SharedMapWithUserContext firstUser = new SharedMapWithUserContext(1);
        SharedMapWithUserContext secondUser = new SharedMapWithUserContext(2);
        new Thread(firstUser).start();
        new Thread(secondUser).start();
        assertEquals(SharedMapWithUserContext.userContextPerUserId.size(), 2);
    }
复制代码

Storing user data in a ThreadLocal

If we want to use in a ThreadLocal you can do:

public class ThreadLocalWithUserContext implements Runnable {

    private static ThreadLocal<Context> userContext
            = new ThreadLocal<>();
    private Integer userId;
    private UserRepository userRepository = new UserRepository();

    public ThreadLocalWithUserContext(int i) {
        this.userId=i;
    }

    @Override
    public void run() {
        String userName = userRepository.getUserNameForUserId(userId);
        userContext.set(new Context(userName));
        System.out.println("thread context for given userId: "
                + userId + " is: " + userContext.get());
    }

}
复制代码

Test code is as follows:

public class ThreadLocalWithUserContextTest {

    @Test
    public void testWithThreadLocal(){
        ThreadLocalWithUserContext firstUser
                = new ThreadLocalWithUserContext(1);
        ThreadLocalWithUserContext secondUser
                = new ThreadLocalWithUserContext(2);
        new Thread(firstUser).start();
        new Thread(secondUser).start();
    }
}
复制代码

After the run, we get the following results:

thread context for given userId: 1 is: com.flydean.Context@411734d4
thread context for given userId: 2 is: com.flydean.Context@1e9b6cc
复制代码

Different user information is stored in a different thread environment.

Note that we use ThreadLocal, it must be thread we can control the freedom of being created. If in ExecutorService environment, it is best not to use ThreadLocal, because in ExecutorService, the thread is not controllable.

Examples described herein may reference github.com/ddean2009/l...

Please refer to more tutorials flydean's blog

Guess you like

Origin juejin.im/post/5e6995d65188254935093512