1 9 package javolution.realtime; 10 11 import java.util.EmptyStackException; 12 import javolution.util.FastMap; 13 14 87 public abstract class Context { 88 89 95 private static FastMap ThreadToContext = new FastMap(); 96 97 100 private static final Object LOCK = new Object(); 101 102 105 private final Thread _owner; 106 107 111 private PoolContext _poolContext; 112 113 117 private Context _outer; 118 119 122 private Context _inner; 123 124 128 protected Context() { 129 _owner = Thread.currentThread(); 130 if (this instanceof PoolContext) { 131 _poolContext = (PoolContext) this; 132 } 133 } 134 135 139 public static void clear() { 140 Context current = Context.currentContext(); 141 if (current._outer == null) { synchronized (Context.LOCK) { Context.ThreadToContext.put(current._owner, null); 144 } 145 } else if (current._outer._inner == current) { 146 current._outer._inner = null; 147 } 148 for (Context ctx = current; ctx != null; ctx = ctx._inner) { 149 ctx.dispose(); 150 } 151 } 152 153 160 protected static Context currentContext() { 161 Context ctx = (Context) Context.ThreadToContext.get(Thread 162 .currentThread()); 163 return (ctx != null) ? ctx : newContext(); 164 } 165 166 private static Context newContext() { 167 Context ctx = (Thread.currentThread() instanceof ConcurrentThread) ? (Context) new PoolContext() 168 : new HeapContext(); 169 synchronized (Context.LOCK) { 170 cleanupDeadThreads(); 171 Context.ThreadToContext.put(ctx._owner, ctx); 172 return ctx; 173 } 174 } 175 176 185 protected final Thread getOwner() { 186 return _owner; 187 } 188 189 195 protected final Context getOuter() { 196 return _outer; 197 } 198 199 206 protected final Context getInner() { 207 return _inner; 208 } 209 210 217 protected static Context push(Class contextClass) { 218 Context current = Context.currentContext(); 219 Context ctx = current._inner; 220 if (contextClass.isInstance(ctx)) { 221 synchronized (Context.LOCK) { 223 Context.ThreadToContext.put(ctx._owner, ctx); 224 return ctx; 225 } 226 } 227 while (ctx != null) { 229 ctx = ctx._inner; 230 if (contextClass.isInstance(ctx)) { Context next = ctx._inner; 233 ctx._outer._inner = next; 234 if (next != null) { 235 next._outer = ctx._outer; 236 } 237 push(ctx); 239 return ctx; 240 } 241 } 242 return null; 243 } 244 245 251 protected static void push(Context ctx) { 252 Context current = Context.currentContext(); 253 ctx._outer = current; 254 ctx._inner = ctx._outer._inner; 255 ctx._outer._inner = ctx; 256 if (ctx._inner != null) { 257 ctx._inner._outer = ctx; 258 } 259 synchronized (Context.LOCK) { 260 Context.ThreadToContext.put(ctx._owner, ctx); 261 } 262 if (!(ctx instanceof PoolContext) && !(ctx instanceof HeapContext)) { 263 ctx._poolContext = ctx._outer._poolContext; 265 } 266 } 267 268 277 protected static Context pop() { 278 Context ctx = Context.currentContext(); 279 if ((ctx._outer != null) && (ctx._outer._owner == ctx._owner)) { 280 synchronized (Context.LOCK) { 281 Context.ThreadToContext.put(ctx._owner, ctx._outer); 282 } 283 return ctx; 284 } else { 285 throw new EmptyStackException(); 286 } 287 } 288 289 293 protected abstract void dispose(); 294 295 301 final PoolContext poolContext() { 302 return _poolContext; 303 } 304 305 310 final void setOuter(Context outer) { 311 _outer = outer; 312 } 313 314 318 private static void cleanupDeadThreads() { 319 int deadThreadCount = 0; 320 for (FastMap.Entry e = Context.ThreadToContext.headEntry(), end = Context.ThreadToContext 321 .tailEntry(); (e = e.getNextEntry()) != end;) { 322 Thread thread = (Thread) e.getKey(); 323 if (!thread.isAlive()) { 324 Context.ThreadToContext.put(thread, null); 325 deadThreadCount++; 326 } 327 } 328 if (deadThreadCount > 256) { FastMap tmp = new FastMap(Context.ThreadToContext.size()); 331 for (FastMap.Entry e = Context.ThreadToContext.headEntry(), end = Context.ThreadToContext 332 .tailEntry(); (e = e.getNextEntry()) != end;) { 333 Thread thread = (Thread) e.getKey(); 334 if (thread.isAlive()) { 335 tmp.put(thread, e.getValue()); 336 } 337 } 338 Context.ThreadToContext = tmp; 339 } 340 } 341 } | Popular Tags |