
public class rw {
        public static void main(String[] args) {

                        testeRdWr t1 = new testeRdWr(0);
                        testeRdWr t2 = new testeRdWr(0);
                        testeRdWr t3 = new testeRdWr(1);
                        /*testeRdWr t4 = new testeRdWr(0);
                        testeRdWr t5 = new testeRdWr(0);
                        testeRdWr t6 = new testeRdWr(1);*/

                        t1.start();
                        t2.start();
                        t3.start();
                        /*t4.start();
                        t5.start();
                        t6.start();

                        testeRdWr t7 = new testeRdWr(0);
                        t7.start();*/
        }
}


class testeRdWr extends Thread {

        int RW;
        static int waitingReaders,waitingWriters;
        static int activeReaders,activeWriters;

        static String texto = "ola mundo";

        public testeRdWr(int RW) {
                this.RW = RW;
        }

        public void run() {

                if(RW == 0) {
                        beforeRead();
                        read();
                        afterRead();
                } else {
                        beforeWrite();
                        write();
                        afterWrite();
                }
        }

        public void read() {
                        System.out.println("Estou a ler! " + texto + activeReaders);
                        try {
                                sleep((int)(Math.random() * 100));
                        } catch (InterruptedException e) { ;}
        }


        public void write() {
                System.out.println("Escrevendo ...");
                texto = "Adeus mundo";
                try {
                        sleep((int)(Math.random() * 100));
                } catch (InterruptedException e) { ;}
        }


        protected boolean allowReader() {
                return(waitingWriters == 0 && activeWriters == 0);
        }

        protected boolean allowWriter() {
                return(activeReaders == 0 && activeWriters == 0);
        }

        protected synchronized void beforeRead() {
                waitingReaders++;
                while(!allowReader())
                        try {
                                wait();
                        } catch(InterruptedException e) { System.out.println("Before Read" + e.getMessage()); }
                        catch(IllegalMonitorStateException ex) { System.out.println("Before Read" + ex.getMessage()); }

                waitingReaders--;
                activeReaders++;

                System.out.println("Waiting Readers: " + waitingReaders + " Active readers:" + activeReaders);
        }

        protected synchronized void afterRead() {
                activeReaders--;
                notifyAll();

                System.out.println("Active Readers:" + activeReaders);

        }

        protected synchronized void beforeWrite() {
                waitingWriters++;
                while(!allowWriter())
                        try {
                                wait();
                        } catch(InterruptedException e) { System.out.println("Before Write" + e.getMessage()); }
                        catch(IllegalMonitorStateException ex) { System.out.println("Before Write" + ex.getMessage()); }
                waitingWriters--;
                activeWriters++;

                System.out.println("Waiting Writers: " + waitingWriters + " Active Writers:" + activeWriters);

        }

        protected synchronized void afterWrite() {
                activeWriters--;
                notifyAll();

                System.out.println("Active Writers:" + activeWriters);

        }

}


