Print service provided by iDogiCat: http://www.idogicat.com/
home logo





Home > IT > Programming > Java > Java Multithreaded Programming > Variables local to a thread

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();
        }
    }
}