ThreadPoolとThreadLoacal その2

Webコンテナ(少なくともTomcat5.0)でPoolされているThreadのThreadLocal.ThreadLocalMapってThreadが再利用されるたびにリフレクションとか使ってクリアーされているわけではないのですね。コードを読んでもわからないのでServlet動かしました。(はじめからこうすればよかった。)
なぜかクリアーされているはずだと思い込んでいましたがそうではありませんでした。気をつけねば。これは実装によってかわってくるんでしょうか。
ThreadLoacalを持つServlet

package hoge;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet extends HttpServlet {
    
    private static ThreadLocal threadLocal = new ThreadLocal();
    
    public void doGet(HttpServletRequest request,
            HttpServletResponse response)
                throws ServletException, IOException {
        Object value = threadLocal.get();
        System.out.println(Thread.currentThread().getName() + " : " + value);
        threadLocal.set("hoge");
    }
}

(何回かGetリクエストを実行して得た)出力結果。get()でnullが返ってくるのはThreadが初めて使われたときだけ。

http-8080-Processor4 : null
http-8080-Processor4 : hoge
http-8080-Processor4 : hoge
http-8080-Processor4 : hoge
http-8080-Processor3 : null
http-8080-Processor3 : hoge
http-8080-Processor3 : hoge
http-8080-Processor3 : hoge
http-8080-Processor3 : hoge
http-8080-Processor4 : hoge
http-8080-Processor3 : hoge
http-8080-Processor3 : hoge

EclipseのDebugビューに表示されるスタック。コピれた。

org.apache.catalina.startup.Bootstrap at localhost:4152
	System Thread [Finalizer] (Running)
	System Thread [Reference Handler] (Running)
	Thread [main] (Running)
	System Thread [Signal Dispatcher] (Running)
	Thread [ContainerBackgroundProcessor[StandardEngine[Catalina]]] (Running)
	Thread [http-8080-Processor1] (Running)
	Thread [http-8080-Processor2] (Running)
	Thread [http-8080-Processor3] (Running)
	Thread [http-8080-Processor4] (Suspended (breakpoint at line 19 in MyServlet))
		MyServlet.doGet(HttpServletRequest, HttpServletResponse) line: 19
		MyServlet(HttpServlet).service(HttpServletRequest, HttpServletResponse) line: 697
		MyServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 810
		ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 237
		ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 157
		StandardWrapperValve.invoke(Request, Response, ValveContext) line: 214
		StandardValveContext.invokeNext(Request, Response) line: 104
		StandardPipeline.invoke(Request, Response) line: 520
		StandardContextValve.invokeInternal(Wrapper, Request, Response) line: 198
		StandardContextValve.invoke(Request, Response, ValveContext) line: 152
		StandardValveContext.invokeNext(Request, Response) line: 104
		StandardPipeline.invoke(Request, Response) line: 520
		StandardHostValve.invoke(Request, Response, ValveContext) line: 137
		StandardValveContext.invokeNext(Request, Response) line: 104
		ErrorReportValve.invoke(Request, Response, ValveContext) line: 117
		StandardValveContext.invokeNext(Request, Response) line: 102
		StandardPipeline.invoke(Request, Response) line: 520
		StandardEngineValve.invoke(Request, Response, ValveContext) line: 109
		StandardValveContext.invokeNext(Request, Response) line: 104
		StandardPipeline.invoke(Request, Response) line: 520
		StandardEngine(ContainerBase).invoke(Request, Response) line: 929
		CoyoteAdapter.service(Request, Response) line: 160
		Http11Processor.process(InputStream, OutputStream) line: 793
		Http11Protocol$Http11ConnectionHandler.processConnection(TcpConnection, Object) line: 702
		TcpWorkerThread.runIt(Object) line: 571
		ThreadPool$ControlRunnable.run() line: 644
		ThreadWithAttributes(Thread).run() line: 534
	Thread [http-8080-Monitor] (Running)
	Thread [TP-Processor1] (Running)
	Thread [TP-Processor2] (Running)
	Thread [TP-Processor3] (Running)
	Thread [TP-Processor4] (Running)
	Thread [TP-Monitor] (Running)