ThreadLocal
ThreadLocalは、変数がスレッド間で分離され、メソッドまたはクラス間で共有されるシナリオに適しています。
コード
@RestController
public class ThreadLocalController {
private static final ThreadLocal<String> currentUid = ThreadLocal.withInitial(() -> null);
@GetMapping("bad")
public Map doBad(@RequestParam("uid") String uid) {
String before = currentUid.get();
currentUid.set(uid);
String after = currentUid.get();
Map result = new HashMap();
result.put("before", before);
result.put("after", after);
return result;
}
}
アプリケーションでTomcatの設定を行います
server.tomcat.max-threads = 1
初めて結果を実行する
2回目
beforeが常にnullであるのは当然のことですが、2回目の実行で最初の時間の値が読み取られるのはなぜですか?
tocatがプログラムを呼び出すためのスレッドを開始し、tomcat自体にスレッドプールがあるという理由だけで、スレッドが再利用されます。それで問題を引き起こしました。
修復
@RestController
public class ThreadLocalController {
private static final ThreadLocal<String> currentUid = ThreadLocal.withInitial(() -> null);
@GetMapping("good")
public Map doGood(@RequestParam("uid") String uid) {
try {
String before = currentUid.get();
currentUid.set(uid);
String after = currentUid.get();
Map result = new HashMap();
result.put("before", before);
result.put("after", after);
return result;
} finally {
currentUid.remove();
}
}
}
キー
Tomcatスレッドプール。