【问题标题】:What happens when the wait method is called inside the method of an object?在对象的方法内部调用 wait 方法会发生什么?
【发布时间】:2013-09-26 10:09:50
【问题描述】:

我在主线程中有如下方法,它在我的数据结构上调用一个方法,如下所示 -:

public static void main(String[] args){

data_structure_object.insert(value);
}

并且我在用于防止线程干扰的数据结构类中使用了一个称为 rwLock 的 ReadWrite 对象,ReadWrite 类如下所示-:

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();
    }

}

在数据结构的insert方法里面,我包含了如下代码sn-p

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

        // Some operation

        // release the lock
        rwLock.unlockRead();

问题是,这是确保公平性并锁定线程以保持数据结构一致性的有效方法吗?除此之外,我不知道如何提供以下功能-:“允许多个读者获取锁并读取数据,直到没有作者请求或写入资源”,我很困惑这种情况请帮忙。

【问题讨论】:

  • 您尝试重新发明轮子的任何原因?
  • 我不是想重新发明轮子,但这是我自己理解的东西。
  • 有一个ReadWriteLock in the JDK with a fairness option。您的代码的一个问题(可能还有其他问题)是一个不持有锁的线程可能会调用解锁并允许多个编写器并行运行。此外,您应该始终在 finally 块中调用 unlock:如果您的代码抛出异常,锁将被永久持有。
  • 您是否可以发现任何其他问题,但是如果当前没有写入器,我如何允许多个读取器获取锁。

标签: java multithreading concurrency locking


【解决方案1】:

除了您试图复制一个完美的现有ReadWriteLock 冒充ReentrantReadWriteLock 之外,您的代码中还有两个特定问题:

  1. 您的实例变量应该是volatile

    private volatile int numberOfReaders = 0;
    private volatile int numberOfWriters = 0;
    private volatile int numberOfWriteRequests = 0;
    
  2. 您需要小心从请求锁定到锁定的转换。

    --numberOfWriteRequests;
    ++numberOfWriters;
    

应该是

    ++numberOfWriters;
    --numberOfWriteRequests;

因为当numberOfWriteRequests 为零且numberOfWriters 为零时,这两条指令之间可能存在一个时刻。这会让你在lockRead 中的自旋循环退出,有时事情会中断。

您可能最好将其移至代码审查。

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-17
    相关资源
    最近更新 更多