Class ThreadContext

java.lang.Object
com.randomnoun.common.ThreadContext

public class ThreadContext extends Object
Can probably do all this with ThreadLocals these days.

Manages a set of hashmaps used by EJB/servlet containers to hold thread-global data.

For example, calling ThreadContext.get("asd") from two different threads may return two different values.

In addition, each thread is supplied with a stack context which allows multiple EJBs to run in the same thread (e.g. if one EJB invokes another local EJB which then executes within the same thread). To ensure separation of data, each EJB should invoke push() to create its own context as soon as it is invoked, and call pop() before it terminates to maintain the per-thread data stack. (i.e. the invoked method, not the method caller is responsible for maintaining data integrity).

This class has all the methods of Map, although these are now static. A real thread-specific java.util.Map object can be obtained by calling the getMap method. Using this object rather than calling static methods on ThreadContext directly may improve performance. The map instance returned by getMap() is not synchronized, since it is assumed that only one thread is accessing it's own context at the same time.

Each EJB (or thread) wishing to use this data structure should clean up after itself by invoking ThreadContext.clear() before passing control back to the EJB container (or terminating). Every thread MUST be removed using .pop(), otherwise memory leaks will occur.

Implementation note: this class relies on different thread's returning unique strings for their Thread.getName() method. It will break if this is not the case in a particular VM implementation.

NB: Don't use this method to pass state between EJBs. Where an EJB invokes a second EJB, it should be assumed that the invoked EJB exists on another VM. Since this data structure will not be populated correctly on the second VM, it should not be relied upon to pass state information between EJBs.

Author:
knoxg
  • Constructor Details

  • Method Details

    • push

      public static Map<Object,Object> push()
      Create a new context for this thread.
      Returns:
      The global map for the newly created context.
    • pop

      public static void pop()
      Remove the most newly-created context for this thread.
      Throws:
      IllegalStateException - This exception is thrown if no context exists for this thread.
    • getMap

      public static Map<Object,Object> getMap()
      Returns a java.util.Map object which contains all thread-specific data. Using the returned object from this method repeatedly from within a single calling method will be more efficient than calling the static methods of this class.
      Returns:
      The map for this thread.
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • contextExists

      public static boolean contextExists()
      Returns true if a ThreadContext has been set up for the current Thread, (through a push() call), false otherwise.
      Returns:
      true if a ThreadContext exists, false otherwise
    • clear

      public static void clear()
      Clears the current EJB's map. This method only clears out the existing thread context, it does not pop the current context off the stack
    • containsKey

      public static boolean containsKey(Object key)
      As per Map.containsKey(java.lang.Object) for the current thread's context
      Returns:
      true if this map contains a mapping for the specified key
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • containsValue

      public static boolean containsValue(Object value)
      As per Map.containsValue(java.lang.Object) for the current thread's context
      Returns:
      true if this map maps one or more keys to the specified value.
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • entrySet

      public static Set<Map.Entry<Object,Object>> entrySet()
      As per Map.entrySet() for the current thread's context
      Returns:
      a set view of the mappings contained in this map.
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • get

      public static Object get(Object key)
      As per Map.get(java.lang.Object) for the current thread's context
      Parameters:
      key - key whose associated value is to be returned.
      Returns:
      the value to which this map maps the specified key, or null if the map contains no mapping for this key
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • isEmpty

      public static boolean isEmpty()
      As per Map.isEmpty() for the current thread's context
      Returns:
      true if this map contains no key-value mappings
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • keySet

      public static Set<Object> keySet()
      As per Map.keySet() for the current thread's context
      Returns:
      a set view of the keys contained in this map
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • put

      public static Object put(Object key, Object value)
      As per Map.put(java.lang.Object, java.lang.Object) for the current thread's context
      Parameters:
      key - key with which the specified value is to be associated
      value - value to be associated with the specified key
      Returns:
      previous value associated with specified key, or null if there was no mapping for key. A null return can also indicate that the map previously associated null with the specified key, if the implementation supports null values
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • putAll

      public static void putAll(Map<Object,Object> t)
      As per Map.putAll(java.util.Map) for the current thread's context
      Parameters:
      t - Mappings to be stored in this map
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • remove

      public static Object remove(Object key)
      As per Map.remove(java.lang.Object) for the current thread's context
      Parameters:
      key - key whose mapping is to be removed from the map
      Returns:
      previous value associated with specified key, or null if there was no mapping for key
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • size

      public static int size()
      As per Map.size() for the current thread's context
      Returns:
      the number of key-value mappings in this map
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().
    • values

      public static Collection<Object> values()
      As per Map.values() for the current thread's context
      Returns:
      a collection view of the values contained in this map
      Throws:
      IllegalStateException - This exception is thrown if a per-thread context has not yet been created by calling push().