Java优化的读/写共享资源/内存位置,无需Atomic API,例如AtomicInteger

use*_*892 1 java concurrency multithreading

有一个共享资源,我们需要按照以下步骤对其执行读/写操作:

  1. 当正在进行资源写操作时,则不允许读取。
  2. 当正在进行读取时,则不允许写入,但应能够读取多个读取线程。

我已经编写了如下所述的代码,但是此代码的问题是,当单个读取线程获得了锁时,所有读取都会被阻止。此外,我正在考虑使用布尔标志,例如canReadContinue。现在,当read第一次获得锁时,我会将此标志翻转为true,如果为true,则其他线程不应尝试获取该锁。

class SharedResource {

    Lock writeLock

    public Object read() {
        writeLock.acquire()
        doRead()

    }

    public void write(Object toBeWritten) {
        writeLock.acquire()

        doWrite(toBeWritten)

        writeLock.release()
    }

}
Run Code Online (Sandbox Code Playgroud)

预期没有写操作时多个线程应该能够读取。

更新1:

公共类SharedResource {

private Object writeLock = new Object();
private volatile boolean canReadContinue;
private volatile int readCount;

public void write(Object newState) throws InterruptedException {
    synchronized (writeLock) {
        // To make sure no read is going on
        while (readCount > 0) {
            wait();
        }
        System.out.println("Write thread has the lock.");
        doWrite(newState);
    }
}

public Object read() {
    if(canReadContinue) {
        incrementCount();
    } else {
        synchronized (writeLock) {
            System.out.println("Read thread has the lock.");
            canReadContinue = true;
            incrementCount();
        }
    }
    Object result = doRead();
    decrementCount();
    if(readCount == 0) {
        // TODO - release lock and notify

    }

    return result;
}

private synchronized void incrementCount() {
    readCount++;
}

private synchronized void decrementCount() {
    readCount--;
}


private void doWrite(Object newState) {
    // do stuff
}

private Object doRead() {
    return "";
}
Run Code Online (Sandbox Code Playgroud)

}

现在,我需要一种在“ // TODO-释放锁并通知”行中释放锁的机制,任何指针如何解决此问题?

Ste*_*n C 5

提示:

  • 您需要一个互斥锁;例如原始对象锁。
  • 您需要一个计数器,该计数器包含当前持有逻辑读取锁的读取器的数量。
  • 您需要一个标志来说明写程序是否持有逻辑写锁。
  • 仅当您正在获取或释放逻辑锁时,才持有互斥量。一旦获得它,就释放互斥量。
  • 您将需要使用waitnotify

有效地,您需要1实现一个简化版本ReadWriteLock


1-...用于您的家庭作业。在现实世界的程序中,您应该只使用现有的ReadWriteLock类。