import java.util.concurrent.locks.*;
import java.util.concurrent.*;
/**
 An example showing how standard read-write lock may deadlock.
 */
public final class DeadlockingReadWriteLock
{
    static ReadWriteLock A = new ReentrantReadWriteLock(false);
    static ReadWriteLock B = new ReentrantReadWriteLock(false);
    //static ReadWriteLock A = new sztejkat.utils.ipc.CReentrantReadWriteLock();
//static ReadWriteLock B = new sztejkat.utils.ipc.CReentrantReadWriteLock();
    static CyclicBarrier synch = new CyclicBarrier(4);

    public static void main(String []a)throws Throwable
    {
//Start readers
        new Thread()
        {
            public void run()
            {
                try{
                    System.out.println("1 - syncing");
                    synch.await();
                    System.out.println("1 - aquiring read lock on A");
                    A.readLock().lock();
                    System.out.println("1 - aquired read lock on A");
                    Thread.sleep(2000);
                    System.out.println("1 - aquiring read lock on B");
                    B.readLock().lock();
                    System.out.println("1 - aquired read lock on B");
                    Thread.sleep(1000);
                    System.out.println("1 - releasing read lock on B");
                    B.readLock().unlock();
                    System.out.println("1 - releasing read lock on A");
                    A.readLock().unlock();
                    System.out.println("1 - done");
                }catch(Exception ex){ System.out.println(ex);};
            };
        }.start();
        new Thread()
        {
            public void run()
            {
                try{
                    System.out.println("2 - syncing");
                    synch.await();
                    Thread.sleep(1000);
                    System.out.println("2 - aquiring read lock on B");
                    B.readLock().lock();
                    System.out.println("2 - aquired read lock on B");
                    Thread.sleep(1000);
                    System.out.println("2 - aquiring read lock on A");
                    A.readLock().lock();
                    System.out.println("2 - aquired read lock on A");
                    Thread.sleep(1000);
                    System.out.println("2 - releasing read lock on A");
                    A.readLock().unlock();
                    System.out.println("2 - releasing read lock on B");
                    B.readLock().unlock();
                    System.out.println("2 - done");
                }catch(Exception ex){ System.out.println(ex);};
            };
        }.start();
        new Thread()
        {
            public void run()
            {
                try{
                    System.out.println("3 - syncing");
                    synch.await();
                    Thread.sleep(1500);
                    System.out.println("3 - aquiring write lock on A");
                    A.writeLock().lock();
                    System.out.println("3 - aquired write lock on A");
                    Thread.sleep(1000);
                    System.out.println("3 - releasing write lock on A");
                    A.writeLock().unlock();
                    System.out.println("3 - A.done()");
                }catch(Exception ex){ System.out.println(ex);};
            };
        }.start();
        new Thread()
        {
            public void run()
            {
                try{
                    System.out.println("4 - syncing");
                    synch.await();
                    Thread.sleep(1500);
                    System.out.println("4 - aquiring write lock on B");
                    B.writeLock().lock();
                    System.out.println("4 - aquired write lock on B");
                    Thread.sleep(1000);
                    System.out.println("4 - releasing write lock on B");
                    B.writeLock().unlock();
                    System.out.println("4 - B.done()");
                }catch(Exception ex){ System.out.println(ex);};
            };
        }.start();
    };
}; 