@Override public void run() { try { for (int i = 0; i < 100; i++) { int sharedBeforeChange = getSharedResource(); int shared = -1; lock.lockShared(); try { // do something needing write lock.lockExclusively(); try { shared = getSharedResource() + 1; // do something Thread.sleep(rnd.nextInt(50)); setSharedResource(shared); lock.lockShared(); try { // do something Thread.sleep(rnd.nextInt(50)); } finally { lock.unlock(); } } finally { lock.unlock(); } } finally { lock.unlock(); } // kick other threads Thread.yield(); // do something Thread.sleep(rnd.nextInt(50)); // This code executes OUTSIDE of critical region! int sharedAfterChange = getSharedResource(); // Assertion (note, it's STRICTLY LESS-THEN): // sharedBeforeChange < shared = sharedAfterChange if (!((sharedBeforeChange < shared) && (shared <= sharedAfterChange))) { throw new IllegalStateException( Thread.currentThread().getName() + " before:" + sharedBeforeChange + " shared:" + shared + " after:" + sharedAfterChange); } } } catch (InterruptedException e) { throw new IllegalStateException(e); } }