package org.code.pomelo.concurrent.concept.locks;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by ruyin on 2017/5/22.
 *
 * 22、(3)==>重进写锁需要线程拥有写的访问权限
 */
public class WriteReentrance {
    private Map<Thread,Integer> readingThreads = new HashMap<>();

    private int writeAccess = 0;
    private int writeRequests = 0;
    //正在写的操作
    private Thread writingThread = null;

    public synchronized void lockWrite() throws InterruptedException {
        writeRequests ++;
        Thread callingThread = Thread.currentThread();
        while (!canGrantWriteAccess(callingThread)){
            wait();
        }
        writeRequests --;
        writeAccess ++;
        writingThread = callingThread;
    }

    public synchronized void unlockWrite(){
        writeAccess --;
        if (writeAccess == 0){
            writingThread = null;
        }
        notifyAll();
    }

    private boolean canGrantWriteAccess(Thread callingThread){
        if (hasReaders()) return false;
        if (writingThread == null) return true;
        if (!isWriter(callingThread)) return false;
        return true;
    }

    //判断是否有读操作的存在
    private boolean hasReaders(){
        return readingThreads.size() > 0;
    }

    //inferred 推断
    private boolean isWriter(Thread callingThread){
        return writingThread == callingThread;
    }
}
