线程本地 - 我做错了什么?

时间:2014-08-08 09:52:34

标签: java spring servlets httprequest thread-local

[IMG] http://i60.tinypic.com/121bww0.jpg[/IMG] (请求高代表用户,请链接图片,它会支持这个问题。)

您好, 根据我的理解,图像描绘了网络应用程序流程。 浏览器向spring调度程序servlet发送请求。 servlet每个请求产生一个新线程(我假设它默认情况下这样做。我不知道如何控制它。) 代码如下:

public class Result{
    private List<String> response = new ArrayList<String>();
    public setResponse(List<String> list){
        this.response = list;
    }

    public list<String> getResponse(){
        return response ;
    }
}

public class ResponseUtil {
    private static final ThreadLocal<Result> responseObject = new  InheritableThreadLocal<Result>();

    public static void initialize(){
        if(responseObject.get() == null){
            Result result= new Result();
            result.setResponse(new ArrayList<String>());
            responseObject.set(result);
        }
    }

    public static void addMessage(String message){
        List<String> messages = responseObject.get().getResponse();
        messages.add(message);
    }

    public static Response getResponse(){
        return responseObject.get();
    }

}

@Component
public class OnboardingEndPointImpl {

    public Result processOnBoardingFile() {
        ResponseUtil.initialize();
        ResponseUtil.addMessage("a"); 

        return ResponseUtil.getResponse();
    }

}

在发送两个休息呼叫时,输出为&#34; a&#34;,&#34; a&#34;。尽管字符串是本地线程,但字符串正在附加到同一列表中。

我的理解是,每个http请求(休息调用)都会生成一个新线程。每次调用都是通过调用initialize()方法开始的。由于每个请求都是一个新的线程,因此每个http请求的threadLocal必须是独立的,但实际上我是线程正在写入同一个列表。所以所有消息都被添加到同一个列表中。 只有当两个调用都是同一个线程时才会发生此行为。

由于

1 个答案:

答案 0 :(得分:6)

实际上,有一个服务请求的线程的。线程被重用于不同的请求。这就是为什么在一个请求的处理完成时无条件清除 ThreadLocal至关重要。你应该使用成语try {} finally { threadLocal.clear(); }

来做