package thread;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 有一个写者很多读者,多个读者可以同时读文件,但写者在写文件时不允许有读者在读文件,同样有读者读时写者也不能写。
 * 读写锁的应用
 */
public class Thread3Test {


    private static class FileTemp {

        private ReentrantReadWriteLock rrw= new ReentrantReadWriteLock();

        public void writeAndReadMoment(int range) {
            try {
                Thread.sleep((int) (range * Math.random()));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public void startWrite() {
            rrw.writeLock().lock();
            System.out.println("1个进程正在写");
        }

        public void endWrite() {
            rrw.writeLock().unlock();
        }

        public void startRead() {
            rrw.readLock().lock();
            System.out.println(Thread.activeCount() + "个进程正在读");
        }
        public void endRead() {
            rrw.readLock().unlock();
        }
    }

    private static class WriteThread extends Thread {
        FileTemp writeFile;

        WriteThread(FileTemp fileTemp) {
            writeFile = fileTemp;
        }

        @Override
        public void run() {
            writeFile.startWrite();
            writeFile.writeAndReadMoment(500);
            writeFile.endWrite();
        }
    }

    private static class ReadThread extends Thread {
        FileTemp readFile;

        ReadThread(FileTemp fileTemp) {
            readFile = fileTemp;
        }

        @Override
        public void run() {
            readFile.startRead();
            readFile.writeAndReadMoment(100);
            readFile.endRead();
        }
    }

    public static void main(String[] args) {
        FileTemp fileTemp=new FileTemp();
        try {
            for (int i=0;i<10;i++)
            {
                WriteThread writeThread = new WriteThread(fileTemp);
                writeThread.start();
                ReadThread readThread = new ReadThread(fileTemp);
                readThread.start();
                ReadThread readThread2 = new ReadThread(fileTemp);
                readThread2.start();
                ReadThread readThread3 = new ReadThread(fileTemp);
                readThread3.start();
                ReadThread readThread4 = new ReadThread(fileTemp);
                readThread4.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}