HTTP REQ --> |Servlet --> 業務ロジック --> DAO1| HTTP RES <-- | --> DAO2| (通常1回の処理要求は1スレッドで処理される)
package com.snail; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; public class ThreadLocalMap extends ThreadLocal<Map<Object, Object>> implements Map<Object, Object> { @Override protected Map<Object, Object> initialValue() { return new LinkedHashMap<Object, Object>(); } public void clear() { ((Map<Object, Object>) get()).clear(); } public boolean containsKey(Object key) { return ((Map<Object, Object>) get()).containsKey(key); } public boolean containsValue(Object value) { return ((Map<Object, Object>) get()).containsValue(value); } public Set<java.util.Map.Entry<Object, Object>> entrySet() { return ((Map<Object, Object>) get()).entrySet(); } public Object get(Object key) { return ((Map<Object, Object>) get()).get(key); } public boolean isEmpty() { return ((Map<Object, Object>) get()).isEmpty(); } public Set<Object> keySet() { return ((Map<Object, Object>) get()).keySet(); } public Object put(Object key, Object value) { return ((Map<Object, Object>) get()).put(key, value); } public void putAll(Map<? extends Object, ? extends Object> m) { ((Map<Object, Object>) get()).putAll(m); } public Object remove(Object key) { return ((Map<Object, Object>) get()).remove(key); } public int size() { return ((Map<Object, Object>) get()).size(); } public Collection<Object> values() { return ((Map<Object, Object>) get()).values(); } }
package com.snail; import java.util.Map; public class ThreadLocalExam { static Map<Object,Object> map = new ThreadLocalMap(); public static void main(String[] args) { Child child1 = new Child("SAKURA"); Child child2 = new Child("MOMO"); Child child3 = new Child("KAEDE"); child1.start(); child2.start(); child3.start(); } static class Child extends Thread{ private String name; public Child(String pName){ name = pName; } @Override public void run(){ System.out.println("THREAD-" + this.getId() + " SET \"" + name + "\" TO MAP"); map.put("NAME", name); try { Thread.sleep(3000L); } catch (InterruptedException ignoreEx) { ignoreEx = null; } System.out.println("THREAD-" + this.getId() + " GET NAME FROM MAP : " + name ); } } }
THREAD-8 SET "SAKURA" TO MAP THREAD-9 SET "MOMO" TO MAP THREAD-10 SET "KAEDE" TO MAP THREAD-8 GET NAME FROM MAP : SAKURA THREAD-10 GET NAME FROM MAP : KAEDE THREAD-9 GET NAME FROM MAP : MOMO
確かにスレッドローカルなMapになっているようだ
public class ServiceContext extends ThreadLocalMap{ public Connection getConnection(){ return (Connection)this.get("CONNECTION"); } public void setConnection( Connection conn ){ this.put("CONNECTION",conn); } public Sring getUserName(){ return (String)this.get("USER_NAME"); } public void setUserName( String userName ){ this.put("USER_NAME",userName); } … }