How to test lock mode compatibility?

Adam Retter adam.retter at
Fri Aug 31 17:57:41 UTC 2018

Hi there,

I am trying to write some tests to check the compatibility of lock
modes. I have an experimental lock implementation which has more modes
that the typical: shared and exclusive.

I am struggling a little to realise the best way to write tests for
checking lock mode compatibility with JCStress.

I will use Java's ReentrantReadWriteLock to illustrate my point, as it
is likely that we are all familiar with it!

I think the lock compatibility matrix for ReentrantReadWriteLock's
lock modes, looks like this:

   | S      | X
S | YES | NO
X | NO   | NO

i.e. if Thread 1 holds the shared (read) lock, then Thread 2 can
simultaneously hold the shared (read) lock, or vice-versa.

I would like to write some JCStress tests to prove the compatibility
of the lock modes.

I can see a simple mechanism for testing this via the #tryLock() methods:

public class ReentrantReadWriteLockBooleanCompatibilityTest {

    public static class S {
        public final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

        public boolean shared() {
            return lock.readLock().tryLock();

        public boolean exclusive() {
            return lock.writeLock().tryLock();

    @Outcome(id = "true, true", expect = Expect.ACCEPTABLE, desc = "T1
and T2 are both acquired S")
    public static class S_S {
        public void actor1(S s, ZZ_Result r) { r.r1 = s.shared(); }
        public void actor2(S s, ZZ_Result r) { r.r2 = s.shared(); }

    @Outcome(id = "true, false", expect = Expect.ACCEPTABLE, desc =
"T1 acquired S, and T2 could not acquire X")
    @Outcome(id = "false, true", expect = Expect.ACCEPTABLE, desc =
"T2 acquired X, and T1 could not acquire S")
    public static class S_X {
        public void actor1(S s, ZZ_Result r) { r.r1 = s.shared(); }
        public void actor2(S s, ZZ_Result r) { r.r2 = s.exclusive(); }

// ...further tests for X_S and X_X omitted for brevity

However, the above involves not releasing the locks, which is fine for
#tryLock because it is non-blocking, but will not work for #lock(). As
such, I am struggling to devise a meaningful way to test with #lock()
instead of #tryLock().

1. For compatible modes I can think of describing the test I want as:
Whilst a thread holds a S mode lock, another thread should be able to
acquire the S mode lock.
2. For incompatible modes as: Whilst a thread holds the X mode lock,
no other thread should be able to acquire the X (or S mode) lock.

I am not quite sure of the correct way to detect when two threads both
hold shared (read) mode locks.
Although, one approach that occurred to me would be to have both
threads increment a shared int. Outcomes might be detectable as:
a) If there are "lost updates" to the int, it would show that it was
updated simultaneously by two threads holding locks with compatible
(shared) modes.
b) If there are no "lost updates", then the threads must not have had
compatible modes.
However, I don't feel entirely comfortable with that approach, as with
(a) I think it would be possible to do the unsynchronized updates to
the int without always exhibiting "lost updates", so we would have a

Can someone suggest a sensible way to do these compatibility checks?

Adam Retter

skype: adam.retter
tweet: adamretter

More information about the jcstress-dev mailing list