1 9 package javolution.realtime; 10 11 import j2me.lang.UnsupportedOperationException; 12 import javolution.JavolutionError; 13 import javolution.lang.Text; 14 15 42 public abstract class RealtimeObject implements Realtime { 43 44 48 private transient Factory.Pool _pool; 49 50 53 private transient RealtimeObject _next; 54 55 58 private transient RealtimeObject _previous; 59 60 63 private transient int _preserved; 64 65 68 protected RealtimeObject() { 69 } 70 71 78 public final String toString() { 79 return toText().stringValue(); 80 } 81 82 87 public Text toText() { 88 return Text.valueOf(getClass().getName()).concat(Text.valueOf('@')) 89 .concat(Text.valueOf(System.identityHashCode(this), 16)); 90 } 91 92 102 public final Object export() { 103 move(ObjectSpace.OUTER); 104 return (Object) this; 105 } 106 107 113 public final Object moveHeap() { 114 move(ObjectSpace.HEAP); 115 return (Object) this; 116 } 117 118 126 public final Object preserve() { 127 move(ObjectSpace.HOLD); 128 return (Object) this; 129 } 130 131 140 public final Object unpreserve() { 141 move(ObjectSpace.LOCAL); 142 return (Object) this; 143 } 144 145 public boolean move(ObjectSpace os) { 147 148 if (os == ObjectSpace.OUTER) { 150 if ((_pool == null) || (!_pool.isLocal())) { 151 return false; } 153 detach(); 154 ObjectPool outer = _pool.getOuter(); 155 if (outer == null) { _next = null; 157 _previous = null; 158 _pool = null; 159 } else { 160 synchronized (outer) { 161 _pool = (Factory.Pool) outer; 162 insertBefore(_pool._next); 163 } 164 } 165 return true; 166 167 } else if (os == ObjectSpace.HEAP) { 169 if (_pool == null) { 170 return false; } 172 synchronized (_pool) { detach(); 174 } 175 _next = null; 176 _previous = null; 177 _pool = null; 178 return true; 179 180 } else if (os == ObjectSpace.HOLD) { 182 synchronized (this) { 183 if (_preserved++ == 0) { 184 if (_pool != null) { 185 synchronized (_pool) { detach(); 187 insertBefore(_pool._holdTail); 188 } 189 } 190 return true; 191 } else { 192 return false; 193 } 194 } 195 196 } else if (os == ObjectSpace.LOCAL) { 198 synchronized (this) { 199 if ((_preserved != 0) && (--_preserved == 0)) { 200 if (_pool != null) { 201 synchronized (_pool) { detach(); 203 insertBefore(_pool._next); 204 } 205 } 206 return true; 207 } else { 208 return false; 209 } 210 } 211 212 } else { 214 return true; } 216 } 217 218 228 protected void recycle() { 229 if (((_pool != null) && _pool.isLocal())) { 230 _pool.recycle(this); 231 } 232 } 233 234 239 final void insertBefore(RealtimeObject next) { 240 _previous = next._previous; 241 _next = next; 242 _next._previous = this; 243 _previous._next = this; 244 } 245 246 250 final void detach() { 251 _next._previous = _previous; 252 _previous._next = _next; 253 } 254 255 259 public static abstract class Factory extends ObjectFactory{ 260 261 264 private Pool _cachedPool = new Pool(); 265 266 269 protected Factory() { 270 } 271 272 278 public final Objectobject() { 279 Pool pool = _cachedPool; 280 if (pool.getUser() == Thread.currentThread()) { 281 final RealtimeObject next = pool._next; 283 final RealtimeObject tmp = pool._next = next._next; 284 return (Object) ((tmp != null) ? next : pool.allocate()); 285 } else { 286 final ObjectPoolcurrentPool = currentPool(); 287 if (currentPool == heapPool()) { 288 return newObject(); 289 } else { 290 _cachedPool = pool = (Pool) currentPool; 291 return pool.next(); 292 } 293 } 294 } 295 296 protected ObjectPoolnewPool() { 298 return new Pool(); 299 } 300 301 304 private final class Pool extends ObjectPool{ 305 306 310 private boolean _doCleanup = true; 311 312 315 private final RealtimeObject _activeHead; 316 317 320 private final RealtimeObject _activeTail; 321 322 325 private final RealtimeObject _holdHead; 326 327 330 private final RealtimeObject _holdTail; 331 332 335 private RealtimeObject _next; 336 337 340 private Pool() { 341 _activeHead = new Bound(); 342 _activeTail = new Bound(); 343 _activeHead._next = _activeTail; 344 _activeTail._previous = _activeHead; 345 346 _holdHead = new Bound(); 347 _holdTail = new Bound(); 348 _holdHead._next = _holdTail; 349 _holdTail._previous = _holdHead; 350 351 _next = _activeTail; 352 } 353 354 public Objectnext() { 355 final RealtimeObject next = _next; 356 _next = next._next; 357 return (Object) ((_next != null) ? next : allocate()); 358 } 359 360 private RealtimeObject allocate() { 361 _next = _activeTail; 362 ObjectPool outer = getOuter(); 363 RealtimeObject obj; 364 if (outer == null) { obj = (RealtimeObject) newObject(); 366 } else { 367 synchronized (outer) { 368 obj = (RealtimeObject) outer.next(); 369 obj.detach(); 370 } 371 } 372 obj.insertBefore(_activeTail); 373 obj._pool = this; 374 return obj; 375 } 376 377 public void recycle(Objectobj) { 378 if (_doCleanup) { 380 try { 381 cleanup(obj); 382 } catch (UnsupportedOperationException ex) { 383 _doCleanup = false; 384 } 385 } 386 387 RealtimeObject rtObj = (RealtimeObject) obj; 388 if (rtObj._pool == this) { 389 rtObj.detach(); 390 rtObj.insertBefore(_next); 391 _next = _next._previous; 392 } else { 393 throw new JavolutionError("Object not in the pool"); 394 } 395 } 396 397 protected void recycleAll() { 398 if (_doCleanup) { 400 try { 401 for (RealtimeObject rt = _activeHead._next; rt != _next;) { 402 cleanup((Object) rt); 403 rt = rt._next; 404 } 405 } catch (UnsupportedOperationException ex) { 406 _doCleanup = false; 407 } 408 } 409 _next = _activeHead._next; 410 } 411 412 protected void clearAll() { 413 _activeHead._next = _activeTail; 414 _activeTail._previous = _activeHead; 415 } 416 } 417 } 418 419 423 private static final class Bound extends RealtimeObject { 424 } 425 } | Popular Tags |