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 }