1 package org.jboss.cache.lock; 2 3 import java.util.concurrent.CyclicBarrier ; 4 import java.util.concurrent.Semaphore ; 5 import java.util.concurrent.TimeUnit ; 6 import java.util.concurrent.locks.Lock ; 7 import junit.framework.Test; 8 import junit.framework.TestCase; 9 import junit.framework.TestSuite; 10 import org.jboss.cache.misc.TestingUtil; 11 12 18 public class LockTest extends TestCase { 19 int value=10; 20 Throwable t1_ex, t2_ex; 21 long start=0; 22 final long TIMEOUT=5000; 23 final long SLEEP=500; 24 25 volatile boolean committed; 26 27 public LockTest(String name) { 28 super(name); 29 } 30 31 32 33 public void tearDown() throws Exception { 34 super.tearDown(); 35 t1_ex=t2_ex=null; 36 committed = false; 37 } 38 39 40 static class MyFIFOSemaphore extends Semaphore { 41 public MyFIFOSemaphore(int permits) { 42 super(permits); 43 } 44 45 public void acquire() throws InterruptedException { 46 super.acquire(); 47 } 48 49 public void release() { 50 super.release(); 51 } 52 } 53 54 55 66 public void testReadUncommitted() throws Throwable { 67 final LockStrategy s=new LockStrategyReadUncommitted(); 68 final Semaphore sem=new MyFIFOSemaphore(1); 69 final CyclicBarrier barrier=new CyclicBarrier (2); 70 71 Thread t1=new Thread ("t1") { 72 Lock lock=null; 73 74 public void run() { 75 try { 76 sem.acquire(); 78 barrier.await(); lock=s.readLock(); 82 lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS); 83 log("1st read: value is " + value); 84 assertEquals(10, value); 85 sem.release(); TestingUtil.sleepThread(100); 87 88 sem.acquire(); log("2nd read: value is " + value + "; we should see t2's uncommitted change (20)"); 90 assertEquals(20, value); sem.release(); 92 TestingUtil.sleepThread(100); 93 94 sem.acquire(); log("3rd read: value is still " + value + "; we should see t2's committed change"); 96 assertEquals(20, value); 97 } 98 catch(Throwable ex) { 99 t1_ex=ex; 100 } 101 finally { 102 if(lock != null) 103 lock.unlock(); 104 sem.release(); 105 } 106 } 107 }; 108 109 110 Thread t2=new Thread ("t2") { 111 Lock lock=null; 112 113 public void run() { 114 try { 115 TestingUtil.sleepThread(100); 116 barrier.await(); 117 sem.acquire(); 118 lock=s.writeLock(); 119 lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS); 120 log("changing value from " + value + " to 20"); 121 value=20; 122 sem.release(); TestingUtil.sleepThread(100); 124 125 sem.acquire(); log("committing the TX"); 127 lock.unlock(); 128 } 129 catch(Throwable ex) { 130 t2_ex=ex; 131 } 132 finally { 133 if(lock != null) 134 lock.unlock(); 135 sem.release(); 136 } 137 } 138 }; 139 140 t1.start(); 141 t2.start(); 142 t1.join(); 143 t2.join(); 144 if(t1_ex != null) 145 throw t1_ex; 146 if(t2_ex != null) 147 throw t2_ex; 148 } 149 150 151 152 166 167 168 171 233 234 235 236 public void testWriteThanRead() throws Throwable { 237 final LockStrategy s=new LockStrategyReadCommitted(); 238 239 Thread t1=new Thread ("t1") { 240 Lock lock=null; 241 242 public void run() { 243 try { 244 TestingUtil.sleepThread(100); 245 lock=s.readLock(); 246 lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS); 247 log("1st read: value is " + value); 248 assertEquals(20, value); 249 TestingUtil.sleepThread(SLEEP); 250 251 log("2nd read: value is " + value + "; we should see t2's uncommitted change (20)"); 252 assertEquals(20, value); TestingUtil.sleepThread(SLEEP); 254 } 255 catch(Throwable ex) { 256 t1_ex=ex; 257 } 258 finally { 259 lock.unlock(); 260 } 261 } 262 }; 263 264 265 Thread t2=new Thread ("t2") { 266 Lock lock=null; 267 268 public void run() { 269 try { 270 lock=s.writeLock(); 271 lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS); 272 log("changing value from " + value + " to 20"); 273 value=20; 274 TestingUtil.sleepThread(SLEEP); 275 276 log("committing the TX"); 277 lock.unlock(); 278 } 279 catch(Throwable ex) { 280 t2_ex=ex; 281 } 282 finally { 283 lock.unlock(); 284 } 285 } 286 }; 287 288 t2.start(); 289 t1.start(); 290 t2.join(); 291 t1.join(); 292 if(t1_ex != null) 293 throw t1_ex; 294 if(t2_ex != null) 295 throw t2_ex; 296 } 297 298 299 300 301 318 public void testRepeatableRead() throws Throwable { 319 final LockStrategy s=new LockStrategyRepeatableRead(); 320 321 Thread t1=new Thread ("t1") { 322 Lock lock=null; 323 324 public void run() { 325 try { 326 lock=s.readLock(); 327 lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS); 328 log("1st read: value is " + value); 329 assertEquals(10, value); 330 TestingUtil.sleepThread(SLEEP); 331 332 log("2nd read: value is " + value + "; we should *not* see t2's uncommitted change (20)"); 333 assertEquals(10, value); 334 TestingUtil.sleepThread(SLEEP); 335 336 log("3rd read: value is still " + value + "; we should not see t2's committed change"); 337 assertEquals(10, value); 338 lock.unlock(); 339 340 TestingUtil.sleepThread(SLEEP); 341 lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS); 342 log("4th read: value is now " + value + "; we should see t2's committed change in our new TX"); 343 assertEquals(20, value); 344 } 345 catch(Throwable ex) { 346 t1_ex=ex; 347 } 348 finally { 349 lock.unlock(); 350 } 351 } 352 }; 353 354 355 Thread t2=new Thread ("t2") { 356 Lock lock=null; 357 358 public void run() { 359 try { 360 TestingUtil.sleepThread(100); 361 lock=s.writeLock(); 362 lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS); 363 log("changing value from " + value + " to 20"); 364 value=20; 365 TestingUtil.sleepThread(SLEEP); 366 367 log("committing the TX"); 368 lock.unlock(); 369 } 370 catch(Throwable ex) { 371 t2_ex=ex; 372 } 373 finally { 374 lock.unlock(); 375 } 376 } 377 }; 378 379 t1.start(); 380 t2.start(); 381 t1.join(); 382 t2.join(); 383 if(t1_ex != null) 384 throw t1_ex; 385 if(t2_ex != null) 386 throw t2_ex; 387 } 388 389 390 403 public void testSerializable() throws Throwable { 404 final LockStrategy s=new LockStrategySerializable(); 405 406 Thread t1=new Thread ("t1") { 407 Lock lock=null; 408 409 public void run() { 410 try { 411 lock=s.readLock(); 412 lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS); 413 log("1st read: value is " + value); 414 assertEquals(10, value); 415 lock.unlock(); 416 TestingUtil.sleepThread(SLEEP); 417 418 lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS); 419 log("2nd read: value is " + value + "; we should see t2's committed change (20)"); 420 assertEquals(20, value); 421 } 422 catch(Throwable ex) { 423 t1_ex=ex; 424 } 425 finally { 426 lock.unlock(); 427 } 428 } 429 }; 430 431 432 Thread t2=new Thread ("t2") { 433 Lock lock=null; 434 435 public void run() { 436 try { 437 TestingUtil.sleepThread(100); 438 lock=s.writeLock(); 439 lock.tryLock(TIMEOUT, TimeUnit.MILLISECONDS); 440 log("changing value from " + value + " to 20"); 441 value=20; 442 log("committing the TX"); 443 lock.unlock(); 444 } 445 catch(Throwable ex) { 446 t2_ex=ex; 447 } 448 finally { 449 lock.unlock(); 450 } 451 } 452 }; 453 454 t1.start(); 455 t2.start(); 456 t1.join(); 457 t2.join(); 458 if(t1_ex != null) 459 throw t1_ex; 460 if(t2_ex != null) 461 throw t2_ex; 462 } 463 464 void log(String s) { 465 long now; 466 if(start == 0) 467 start=System.currentTimeMillis(); 468 now=System.currentTimeMillis(); 469 470 System.out.println("[" + Thread.currentThread().getName() + "] [" + (now - start) + "] " + s); 471 } 472 473 474 public static void main(String [] args) throws Exception { 475 junit.textui.TestRunner.run(suite()); 476 } 477 478 public static Test suite() { 480 TestSuite suite=new TestSuite(); 481 suite.addTestSuite(LockTest.class); 482 return suite; 483 } 484 485 486 487 488 } 489 490 | Popular Tags |