简体   繁体   中英

What happens when the wait method is called inside the method of an object?

I have method like the following in the main thread, that invokes a method on my data structure as follows -:

public static void main(String[] args){

data_structure_object.insert(value);
}

and I am using a ReadWrite object call it rwLock inside the data structure class that is used to prevent thread interference, the Read Write class looks like the following -:

public class ReadWriteLocks {

    // these 3 variables help in creating a read write lock
    private int numberOfReaders = 0;
    private int numberOfWriters = 0;
    private int numberOfWriteRequests = 0;

    // getter method for the number of readers
    public int getNumberOfReaders() {
        return this.numberOfReaders;
    }

    // getter method for the number of writers
    public int getNumberOfWriters() {
        return this.numberOfWriters;
    }

    // getter method for the number of write requests
    public int getNumberOfWriteRequests() {
        return this.numberOfWriteRequests;
    }

    // this function checks if a thread can acquire the lock
    public synchronized void lockRead() throws InterruptedException {

        while (numberOfWriters > 0 || numberOfWriteRequests > 0)
            this.wait();
    }

    // this function unlocks a lock occupied by a reader thread
    public synchronized void unlockRead() {

        // decrement the number of readers
        --numberOfReaders;
        notifyAll();
    }

    // this function checks if a thread can acquire the write lock
    public synchronized void lockWrite() throws InterruptedException {

        // increase the number of write requests
        ++numberOfWriteRequests;

        while (numberOfReaders > 0 || numberOfWriters > 0)
            this.wait();

        --numberOfWriteRequests;
        ++numberOfWriters;
    }

    // this function is used to take a thread away from the lock
    public synchronized void unlockWrite() {

        // decrement the number of writers
        --numberOfWriters;

        // notify all the threads
        this.notifyAll();
    }

}

and inside the insert method of the data structure, I include the following code snippet

// acquire the read/write lock
        try {
            rwLock.lockRead();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Some operation

        // release the lock
        rwLock.unlockRead();

The question is, Is this a valid way of ensuring fairness and also locking threads so as to maintain the data structure consistency? also besides all this I am not able to figure out how shall I provide the following functionality -: "Allowing multiple Readers to acquire the lock and reading the data till there is no writer requesting or writing to the resource" , I am pretty confused about the situation kindly help.

Apart from the fact that you are attempting to duplicate a perfectly good existing ReadWriteLock posing as a ReentrantReadWriteLock there are two certain issues in your code:

  1. Your instance variables should be volatile .

     private volatile int numberOfReaders = 0; private volatile int numberOfWriters = 0; private volatile int numberOfWriteRequests = 0; 
  2. You need to be careful with your transition from lock-requested to locked.

     --numberOfWriteRequests; ++numberOfWriters; 

probably should be

    ++numberOfWriters;
    --numberOfWriteRequests;

because there could be a moment between those two instructions when numberOfWriteRequests is zero and numberOfWriters is zero. This would let your spin loop in lockRead out and things would break ... sometimes.

You would probably be best to get this moved to code review.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM