ThreadLocal problem running in tomcat container prone

ThreadLocal life cycle tomcat container does not mean web request life cycle, so (discussed below tomcat container is used ThreadLocal), so ThreadLocal should not be saved and will affect the request of the relevant information.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("threadLocalRunInTomcatTest")
public class ThreadLocalRunInTomcatTestController {

    private static final ThreadLocal<String> currentUserId = ThreadLocal.withInitial(() -> null);

    @GetMapping("fail")
    public String fail(@RequestParam("uid") String uid) {
        String before  = Thread.currentThread().getName() + ":" + currentUserId.get();
        currentUserId.set(uid);
        String after  = Thread.currentThread().getName() + ":" + currentUserId.get();
        return before+"\n"+after;
    }

    @GetMapping("success")
    public String success(@RequestParam("userId") String userId) {
        String before  = Thread.currentThread().getName() + ":" + currentUserId.get();
        currentUserId.set(userId);
        try {
            String after = Thread.currentThread().getName() + ":" + currentUserId.get();
            return before+"\n"+after;
        } finally {
            currentUserId.remove();
        }
    }
}

Requests fail the first test:
currentUserId is used to store the current user's unique key,
the first request 127.0.0.1:1003/threadLocalRunInTomcatTest/fail?uid=2
return results as:
HTTP-NiO-1003-Exec-1: null
HTTP-NiO-1003--Exec. 1: 2
at this time is the result;

127.0.0.1:45678/threadLocalRunInTomcatTest/fail?uid=3 second request
(the uid to the value 3)
results:
HTTP-NiO-45678-Exec. 1-: 2
HTTP-NiO-45678-Exec. 1-: 3

Analysis:
We returned data format is: return before + "\ n" + after;
so the first time, before is null, after 2
second, before to 2, after three.
Apparent, web request cycle different from the cycle threadLocal; this is too expensive because the thread creation, the reused. After know the reason, you can delete data at the end of localthread add a remove.

Request a test of success:
127.0.0.1:45678/threadLocalRunInTomcatTest/success?userId=2

No matter how many times the request, each time returned:
HTTP-NiO-45678-Exec-1: null
HTTP-NiO-45678-Exec-1: 2

Released two original articles · won praise 1 · views 13

Guess you like

Origin blog.csdn.net/qq_24510649/article/details/105013382