View Javadoc

1   package org.e2etrace.trace;
2   
3   /*
4    * Copyright 2006 Gunther Popp
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.util.Collections;
20  import java.util.Map;
21  import java.util.WeakHashMap;
22  
23  /**
24   * Thread-Aware implementation of a trace session manager.
25   * <p>
26   *
27   * This session manager is targeted for a multi-threaded environment (e.g.
28   * application servers). It maintains a {@link org.e2etrace.trace.ITraceSession} for
29   * every running thread.
30   * <p>
31   *
32   * <em>Note:</em> The implementation uses a synchronized
33   * <code>WeakHashMap</code> to cache the sessions (using the threads as keys).
34   * Hence, as soon as a thread terminates, the GC will remove the respective
35   * cache entry automatically. This design works for multi-threaded applications
36   * and for application servers using thread pools. An alternative design would
37   * have been to use <code>ThreadLocal</code> instead. However, there are
38   * discussions going on that <code>ThreadLocal</code> may cause memory leaks
39   * on application servers if applications are hot-deployed (just google for
40   * threadlocal+leak). Personally, I would prefer <code>ThreadLocal</code>
41   * instead of the custom cache that is currently implemented, because the
42   * <code>ThreadLocal</code> approache doesn´t require a synchronized map that
43   * stores the trace sessions. I´ll monitor the memory-leak discussion and decide
44   * later, if a re-design is appropriate.
45   * <p>
46   *
47   * This class implements the singleton pattern.
48   * <p>
49   *
50   * @author Gunther Popp
51   *
52   */
53  public class ThreadedTraceSessionManager extends AbstractTraceSessionManager {
54  
55    private static final ThreadedTraceSessionManager instance = new ThreadedTraceSessionManager();
56  
57    private Map sessionCache;
58  
59    /**
60     * Returns the singleton instance of the session manager.
61     * <p>
62     *
63     * @return trace session manager
64     */
65    public static ThreadedTraceSessionManager getInstance() {
66      return instance;
67    }
68  
69    /**
70     * Default constructor.
71     * <p>
72     *
73     */
74    private ThreadedTraceSessionManager() {
75      super();
76  
77      this.sessionCache = Collections.synchronizedMap(new WeakHashMap());
78    }
79  
80    /** {@inheritDoc} */
81    protected ITraceSession requestCurrentSession() {
82      return (ITraceSession) this.sessionCache.get(Thread.currentThread());
83    }
84  
85    /** {@inheritDoc} */
86    protected void assignCurrentSession(ITraceSession session) {
87      this.sessionCache.put(Thread.currentThread(), session);
88    }
89  
90    /** {@inheritDoc} */
91    public void releaseCurrentSession() {
92      this.sessionCache.remove(Thread.currentThread());
93    }
94  
95  }