Variables local to a thread
In multithreaded programs, it's always tricky to avoid threads from stepping on feet of each other. So it's really a great idea to have variables local to a thread. In Java, this is implemented by extending ThreadLocal class.
MyThreadLocalVar extends ThreadLocal <MyType> () {
@Override
protected MyType initialValue() {
return ...;
}
Usage Demo
Make a thread local hash map.
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
class ThreadLocalMap<T1, T2> extends ThreadLocal<Map<T1, T2>> implements
Map<T1, T2> {
@Override
protected Map<T1, T2> initialValue() {
return new LinkedHashMap<T1, T2>();
}
public void clear() {
get().clear();
}
public boolean containsKey(Object key) {
return get().containsKey(key);
}
public boolean containsValue(Object value) {
return get().containsValue(value);
}
public Set<java.util.Map.Entry<T1, T2>> entrySet() {
return get().entrySet();
}
public T2 get(Object key) {
return get().get(key);
}
public boolean isEmpty() {
return get().isEmpty();
}
public Set<T1> keySet() {
return get().keySet();
}
public T2 put(T1 key, T2 value) {
return get().put(key, value);
}
public void putAll(Map<? extends T1, ? extends T2> m) {
get().putAll(m);
}
public T2 remove(Object key) {
return get().remove(key);
}
public int size() {
return get().size();
}
public Collection<T2> values() {
return get().values();
}
}
class ServiceContext extends ThreadLocalMap<String, Object> {
private static final String USER = "USER";
private static final String CONN = "CONN";
public String getUserName(){
return (String)get(USER);
}
public void setUserName( String userName ){
put(USER, userName);
}
public Object getConnection(){
return get(CONN);
}
public void setConnection(Object conn ){
put(CONN, conn);
}
// ...
}
public class Main {
static ServiceContext context = new ServiceContext();
static class MyService extends Thread{
private String user;
public MyService(String user){
this.user = user;
}
@Override
public void run(){
System.out.println("Assign thread No. " + getId() + " to handle
request from user " + user);
context.setUserName(user);
try {
// do some work...
Thread.sleep(5000L);
} catch (InterruptedException e) {
ignoreEx = null;
}
System.out.println("Thread No. " + getId() + " handled request
from user " + context.getUserName());
}
}
// test
public static void main(String[] args) {
String[] users = {"Tom", "Mike", "Jane", "Marry", "Bruce", "Robecca",
"Melissa"};
for(int i = 0; i < users.length; i++) {
new MyService(users[i]).start();
}
}
}