import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.locks.StampedLock;

// original test by Dmitry Chyuko
// HANGS on error
public class CowaitCBTestSL {
    static final int RNUM = 2;
    static StampedLock sl = new StampedLock();
    static volatile boolean isDone;

    static CyclicBarrier iterationStart = new CyclicBarrier(RNUM + 1);
    static CyclicBarrier readersHaveLocks = new CyclicBarrier(RNUM);
    static CyclicBarrier writerHasLock = new CyclicBarrier(RNUM + 1);

    static class Reader extends Thread {
        final String name;
        Reader(String name) {
            super();
            this.name = name;
        }
        public void run() {
            while(!isDone && !isInterrupted()) {
                try {
                    iterationStart.await();
                    writerHasLock.await();
                    long rs = sl.readLock();
                    readersHaveLocks.await();
                    sl.unlockRead(rs);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for(int r = 0 ; r < RNUM; ++r) {
            new Reader("r" + r).start();
        }
        int i;
        for(i = 0; i < 1024; ++i) {
            try {
                iterationStart.await();
                long ws = sl.writeLock();
                writerHasLock.await();
                Thread.sleep(10);
                sl.unlockWrite(ws);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        isDone = true;
    }

}
