1 21 package oracle.toplink.essentials.internal.helper; 23 24 import java.io.*; 25 import java.util.*; 26 import oracle.toplink.essentials.exceptions.*; 27 import oracle.toplink.essentials.internal.localization.*; 28 import oracle.toplink.essentials.internal.identitymaps.CacheKey; 29 import oracle.toplink.essentials.logging.*; 30 31 44 public class ConcurrencyManager implements Serializable { 45 protected int numberOfReaders; 46 protected int depth; 47 protected int numberOfWritersWaiting; 48 protected transient Thread activeThread; 49 public static Hashtable deferredLockManagers; 50 protected boolean lockedByMergeManager; 51 52 55 protected CacheKey ownerCacheKey; 56 57 61 public ConcurrencyManager() { 62 this.depth = 0; 63 this.numberOfReaders = 0; 64 this.numberOfWritersWaiting = 0; 65 } 66 67 71 public ConcurrencyManager(CacheKey cacheKey) { 72 this(); 73 this.ownerCacheKey = cacheKey; 74 } 75 76 81 public synchronized void acquire() throws ConcurrencyException { 82 this.acquire(false); 83 } 84 85 91 public synchronized void acquire(boolean forMerge) throws ConcurrencyException { 92 while (!((getActiveThread() == Thread.currentThread()) || ((getActiveThread() == null) && (getNumberOfReaders() == 0)))) { 93 try { 95 setNumberOfWritersWaiting(getNumberOfWritersWaiting() + 1); 96 wait(); 97 setNumberOfWritersWaiting(getNumberOfWritersWaiting() - 1); 98 } catch (InterruptedException exception) { 99 throw ConcurrencyException.waitWasInterrupted(exception.getMessage()); 100 } 101 } 102 if (getActiveThread() == null) { 103 setActiveThread(Thread.currentThread()); 104 } 105 setIsLockedByMergeManager(forMerge); 106 setDepth(getDepth() + 1); 107 108 } 109 110 115 public synchronized boolean acquireNoWait() throws ConcurrencyException { 116 if (!isAcquired() || getActiveThread() == Thread.currentThread()) { 117 acquire(false); 119 return true; 120 } else { 121 return false; 122 } 123 } 124 125 131 public synchronized boolean acquireNoWait(boolean forMerge) throws ConcurrencyException { 132 if (!isAcquired() || getActiveThread() == Thread.currentThread()) { 133 acquire(forMerge); 135 return true; 136 } else { 137 return false; 138 } 139 } 140 141 144 public void acquireDeferredLock() throws ConcurrencyException { 145 Thread currentThread = Thread.currentThread(); 146 DeferredLockManager lockManager = getDeferredLockManager(currentThread); 147 if (lockManager == null) { 148 lockManager = new DeferredLockManager(); 149 putDeferredLock(currentThread, lockManager); 150 } 151 lockManager.incrementDepth(); 152 synchronized (this) { 153 while (!(getNumberOfReaders() == 0)) { 154 try { 161 setNumberOfWritersWaiting(getNumberOfWritersWaiting() + 1); 162 wait(); 163 setNumberOfWritersWaiting(getNumberOfWritersWaiting() - 1); 164 } catch (InterruptedException exception) { 165 throw ConcurrencyException.waitWasInterrupted(exception.getMessage()); 166 } 167 } 168 if ((getActiveThread() == currentThread) || (!isAcquired())) { 169 lockManager.addActiveLock(this); 170 acquire(); 171 } else { 172 lockManager.addDeferredLock(this); 173 Object [] params = new Object [2]; 174 params[0] = this.getOwnerCacheKey().getObject(); 175 params[1] = currentThread.getName(); 176 AbstractSessionLog.getLog().log(SessionLog.FINER, "acquiring_deferred_lock", params, true); 177 } 178 } 179 } 180 181 185 public void checkReadLock() throws ConcurrencyException { 186 if (getActiveThread() == null) { 188 return; 189 } 190 acquireReadLock(); 191 releaseReadLock(); 192 } 193 194 198 public synchronized void acquireReadLock() throws ConcurrencyException { 199 while (!((getActiveThread() == Thread.currentThread()) || (getActiveThread() == null))) { 201 try { 202 wait(); 203 } catch (InterruptedException exception) { 204 throw ConcurrencyException.waitWasInterrupted(exception.getMessage()); 205 } 206 } 207 208 setNumberOfReaders(getNumberOfReaders() + 1); 209 } 210 211 214 public synchronized boolean acquireReadLockNoWait() { 215 if (!isAcquired()) { 216 acquireReadLock(); 217 return true; 218 } else { 219 return false; 220 } 221 } 222 223 226 public Thread getActiveThread() { 227 return activeThread; 228 } 229 230 233 public synchronized static DeferredLockManager getDeferredLockManager(Thread thread) { 234 return (DeferredLockManager)getDeferredLockManagers().get(thread); 235 } 236 237 240 protected static Hashtable getDeferredLockManagers() { 241 if (deferredLockManagers == null) { 242 deferredLockManagers = new Hashtable(50); 243 } 244 245 return deferredLockManagers; 246 } 247 248 251 public int getDepth() { 252 return depth; 253 } 254 255 259 public int getNumberOfReaders() { 260 return numberOfReaders; 261 } 262 263 267 public int getNumberOfWritersWaiting() { 268 return numberOfWritersWaiting; 269 } 270 271 274 public CacheKey getOwnerCacheKey() { 275 return this.ownerCacheKey; 276 } 277 278 281 public boolean isAcquired() { 282 return depth > 0; 283 } 284 285 290 public boolean isLockedByMergeManager() { 291 return this.lockedByMergeManager; 292 } 293 294 297 public synchronized static boolean isBuildObjectOnThreadComplete(Thread thread, IdentityHashtable recursiveSet) { 298 if (recursiveSet.containsKey(thread)) { 299 return true; 300 } 301 recursiveSet.put(thread, thread); 302 303 DeferredLockManager lockManager = getDeferredLockManager(thread); 304 if (lockManager == null) { 305 return true; 306 } 307 308 Vector deferredLocks = lockManager.getDeferredLocks(); 309 for (Enumeration deferredLocksEnum = deferredLocks.elements(); 310 deferredLocksEnum.hasMoreElements();) { 311 ConcurrencyManager deferedLock = (ConcurrencyManager)deferredLocksEnum.nextElement(); 312 Thread activeThread = null; 313 if (deferedLock.isAcquired()) { 314 activeThread = deferedLock.getActiveThread(); 315 316 if (activeThread != null) { 319 DeferredLockManager currentLockManager = getDeferredLockManager(activeThread); 320 if (currentLockManager == null) { 321 return false; 322 } else if (currentLockManager.isThreadComplete()) { 323 activeThread = deferedLock.getActiveThread(); 324 if (activeThread != null) { 326 if (!isBuildObjectOnThreadComplete(activeThread, recursiveSet)) { 327 return false; 328 } 329 } 330 } else { 331 return false; 332 } 333 } 334 } 335 } 336 return true; 337 } 338 339 342 public boolean isNested() { 343 return depth > 1; 344 } 345 346 public synchronized void putDeferredLock(Thread thread, DeferredLockManager lockManager) { 347 getDeferredLockManagers().put(thread, lockManager); 348 } 349 350 357 public synchronized void release() throws ConcurrencyException { 358 if (getDepth() == 0) { 359 throw ConcurrencyException.signalAttemptedBeforeWait(); 360 } else { 361 setDepth(getDepth() - 1); 362 } 363 if (getDepth() == 0) { 364 setActiveThread(null); 365 setIsLockedByMergeManager(false); 366 notifyAll(); 367 } 368 } 369 370 376 public void releaseDeferredLock() throws ConcurrencyException { 377 Thread currentThread = Thread.currentThread(); 378 DeferredLockManager lockManager = getDeferredLockManager(currentThread); 379 if (lockManager == null) { 380 return; 381 } 382 int depth = lockManager.getThreadDepth(); 383 384 if (depth > 1) { 385 lockManager.decrementDepth(); 386 return; 387 } 388 389 if (!lockManager.hasDeferredLock()) { 391 lockManager.releaseActiveLocksOnThread(); 392 removeDeferredLockManager(currentThread); 393 return; 394 } 395 396 lockManager.setIsThreadComplete(true); 397 398 while (true) { 403 IdentityHashtable recursiveSet = new IdentityHashtable(); 405 if (isBuildObjectOnThreadComplete(currentThread, recursiveSet)) { lockManager.releaseActiveLocksOnThread(); 407 removeDeferredLockManager(currentThread); 408 Object [] params = new Object [1]; 409 params[0] = currentThread.getName(); 410 AbstractSessionLog.getLog().log(SessionLog.FINER, "deferred_locks_released", params, true); 411 return; 412 } else { try { 414 Thread.sleep(10); 415 } catch (InterruptedException ignoreAndContinue) { 416 } 417 } 418 } 419 } 420 421 425 public synchronized void releaseReadLock() throws ConcurrencyException { 426 if (getNumberOfReaders() == 0) { 427 throw ConcurrencyException.signalAttemptedBeforeWait(); 428 } else { 429 setNumberOfReaders(getNumberOfReaders() - 1); 430 } 431 if (getNumberOfReaders() == 0) { 432 notifyAll(); 433 } 434 } 435 436 439 public synchronized static DeferredLockManager removeDeferredLockManager(Thread thread) { 440 return (DeferredLockManager)getDeferredLockManagers().remove(thread); 441 } 442 443 446 public void setActiveThread(Thread activeThread) { 447 this.activeThread = activeThread; 448 } 449 450 453 protected void setDepth(int depth) { 454 this.depth = depth; 455 } 456 457 462 public void setIsLockedByMergeManager(boolean state) { 463 this.lockedByMergeManager = state; 464 } 465 466 469 protected void setNumberOfReaders(int numberOfReaders) { 470 this.numberOfReaders = numberOfReaders; 471 } 472 473 477 protected void setNumberOfWritersWaiting(int numberOfWritersWaiting) { 478 this.numberOfWritersWaiting = numberOfWritersWaiting; 479 } 480 481 484 public String toString() { 485 Object [] args = { new Integer (getDepth()) }; 486 return Helper.getShortClassName(getClass()) + ToStringLocalization.buildMessage("nest_level", args); 487 } 488 } 489 | Popular Tags |