Is there a read write lock with listeners for Java?

Is there a Java library that implements something that behaves like ReadWriteLockbut uses listeners or CompletableFuture / CompletionStage instead of locking?

Ideally, I would like to write:

lock = ...

CompletionStage stage = lock.lockRead();
stage.thenAccept(r -> { doSomething(); r.release(); });

And also important:

CompletionStage stage = lock.tryLockWrite(10, TimeUnit.SECONDS);
stage.handle(callback);

I want to know if something like this exists, and if so, what is it called.

I am not going to implement this myself, but rather use a library to simplify some infrastructure code.

+4
source share
1 answer

I think that writing it yourself should not be difficult enough. Most likely, it will take less time than finding a library. It is pretty simple:

static const int STATE_UNLOCKED = 0;
static const int STATE_READING = 1;
static const int STATE_WRITING = 2;
int state = STATE_UNLOCKED;
int readers = 0;
Queue<CompletableFuture<Void>> queueWriters = new LinkedList<CompletableFuture<Void>>();
Queue<CompletableFuture<Void>> queueReaders = new LinkedList<CompletableFuture<Void>>();

public synchronized CompletionStage<Void> lockWriter() {
    CompletableFuture<Void> l = new CompletableFuture<Void>();
    if (state == STATE_UNLOCKED) {
        state = STATE_WRITING;
        l.complete(null);
        return l;
    }
    queueWriters.offer(l);
    return l;
}

public synchronized CompletionStage<Void> lockReader() {
    CompletableFuture<Void> l = new CompletableFuture<Void>();
    if (state != STATE_WRITING) {
        state = STATE_READING;
        readers++;
        l.complete(null);
        return l;
    }
    queueReaders.offer(l);
    return l;
}

public void unlock() {
    CompletableFuture<Void> l = null;
    synchronized(this) {
        if (state == STATE_READING) {
            readers--;
            if (readers > 0) {
                return;
            }
        }
        l = queueReaders.poll();
        if (l != null) {
            state = STATE_READING;
            readers++;
        }
        else {
            l = queueWriters.poll();
            if (l != null) {
                state = STATE_WRITING;
            }
            else {
                state = STATE_UNLOCKED;
                return;
            }
        }
    }
    l.complete(null);
    while (true) {
        synchronized (this) {
            if (state != STATE_READING) {
                return;
            }
            l = queueReaders.poll();
            if (l == null) {
                return;
            }
            readers++;
        }
        l.complete(null);
    }
}

- ( - " " ( , queueWriters ), .

+2

All Articles