2015-04-05 76 views
4

是否有一個java庫實現的行爲類似於ReadWriteLock,但使用偵聽器或CompletableFuture/CompletionStage而不是阻塞?是否有一個讀監聽器的Java寫鎖?

理想我想這樣寫:

lock = ... 

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

而且也很重要:

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

我希望知道,如果這樣的事情存在,如果它確實如何它叫做

我不想自己實現這個,而是使用庫來簡化一些框架代碼。

+0

這是'java-8' with lambdas,對吧? – Andremoniy 2015-04-05 15:59:12

+0

沒錯,但我沒有要求lambda表達式,但是CompletionStage只適用於java-8 – 2015-04-05 16:05:55

+0

這個語義是什麼ReadWriteLock和CompletableFuture是什麼?一個CompletableFutures處理程序被另一個線程在未來的某個特定時間調用。你的意思是擴展讀鎖直到那隻手ler在另一個線程中完成,重新獲取完成的鎖,或者在完成期間沒有鎖? – meriton 2015-04-05 19:58:48

回答

2

我覺得自己寫就不應該夠難。有機會比尋找圖書館花費更少的時間。這是很簡單的整體:

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不爲空,正在執行)以上不應該

+0

所以,我已經用這樣的東西解決了我的問題。不過,我正在尋找一個帶有[「Doug Lea」](https://en.wikipedia.org/wiki/Doug_Lea)質量水平的圖書館。 – 2015-04-06 01:22:49

+1

談到promises/async時,沒有比使用隊列更好的解決方案。沒有相同數量的線程運行,它不像你可以旋轉鎖定。如果你足夠努力的搜索,你可能會發現一些預先打包的東西,但不一定「更好」。在我的實現中可以改進的一件事是在synchronized塊中發生的「lockReader」和「lockWriter」中調用「complete」。或者,如果保證單線程操作(Event循環?),則可以完全跳過同步。 – SlugFiller 2015-04-06 08:14:46