JAva読み書きロックによる単純キャッシュ

2305 ワード

読み書きロック規則:
読み取りと読み取りは反発しない(したがって、複数のスレッドは同時に読むことができる)、読み取りと書き込みは反発し、書き込みと書き込みは反発する.
読み書きが少ない場合に適しています.
public class Cache {

    //              ,        。
    private final  Map map = new HashMap<>(); 

    private ReadWriteLock lock = new ReentrantReadWriteLock();

    final Lock readLock = lock.readLock();

    final Lock writeLock = lock.writeLock();


    //        ,try{    } finally{   }      
    public V get(K k){
        readLock.lock();
        try {
            return map.get(k);
        }finally {
            readLock.unlock();

        }
    }

    public void set(K k , V v){
        try {
            writeLock.lock();
            map.put(k,v);
        }finally {
            writeLock.unlock();
        }
    }
}

読み書きロックのダウングレードとアップグレード:
ダウングレード:つまり、書き込みロックを取得した場合に読み取りロックを取得することは許可されます.書き込みロックを取得したため、他のスレッドは読み取りロックを取得できないため、可能です.
≪アップグレード|Upgrade|emdw≫:読み取りロックを取得した場合に書き込みロックを取得することは許可されず、ブロックされます.
StampedLockロック
stampedLockロックは読み書きロックよりも効率が高く、ロックモードは書き込みロック、悲観的な読み取りロック、楽観的な読み取りです.このうち,書き込みロック,悲観リードロックの意味はReadWriteLockの書き込みロック,リードロックの意味と非常に類似しており,複数のスレッドが同時に悲観リードロックを取得することを可能にするが,1つのスレッドのみが書き込みロックを取得することを可能にし,書き込みロックと悲観リードロックは反発する.違いは、StampedLockの書き込みロックと悲観的な読み取りロックが成功すると、stampが返されます.そしてロックを解除するときは、このstampに転送する必要があります.
StampedLockのパフォーマンスがReadWriteLockよりも優れているのは、StampedLockが楽観的な読み取りをサポートする方法が鍵です.ReadWriteLockは複数のスレッドの同時読み取りをサポートしますが、複数のスレッドが同時に読むと、すべての書き込み操作がブロックされます.StampedLockが提供する楽観的な読み取りは、1つのスレッドが書き込みロックを取得することを許可します.つまり、すべての書き込み操作がブロックされているわけではありません.
楽観的にこの操作を読むとロックがありません
最下位はバージョンによって感知データが修正されたかどうか、リードロックを行うたびにバージョン修正が行われ、修正されたかどうかを知ることができます.
読み取りテンプレート:
final StampedLock sl = 
  new StampedLock();

//    
long stamp = 
  sl.tryOptimisticRead();
//         
......
//    stamp
if (!sl.validate(stamp)){
  //        
  stamp = sl.readLock();
  try {
    //         
    .....
  } finally {
    //       
    sl.unlockRead(stamp);
  }
}
//               
......

書き込みテンプレート:
long stamp = sl.writeLock();
try {
  //      
  ......
} finally {
  sl.unlockWrite(stamp);
}

tip:
StampedLockでは割り込み操作を呼び出さないでください.割り込み機能をサポートする必要がある場合は、割り込み可能な悲観的な読み取りロックreadLockInterruptibly()と書き込みロックwriteLockInterruptibly()を使用します.