キャッシュ実現


各位のエビ、私は1つの高速のキャッシュを実現して、実現の方式の中でjavaのconcurrentに頼ってConcerendHashMapを包んで、コードを貼って、各位が下記のaddElement()の方法を討論してロックをプラスしないことを望んで、スレッドの問題が現れることができますか?(本人の理解ではできないはずです。私は才能が浅いので、教えてください。また、この方法の実現は<java同時プログラミング実践>を参照してください。)

public class Cache<K, V> {
	
	private final ConcurrentHashMap<K, FutureTask<V>> cache = 
								new ConcurrentHashMap<K, FutureTask<V>>();
	
	private final ReadWriteLock lock = new ReentrantReadWriteLock();
	private final Lock readLock = lock.readLock();
//	private final Lock writeLock = lock.writeLock();
	
	public V addElement(final K key, final V value) {
		FutureTask<V> f = cache.get(key);
		while (true) {
			if (null == f) {
				Callable<V> eval = new Callable<V>() {

					@Override
					public V call() throws Exception {
						//        ,        V             ,
						//             
						return value;
					}
					
				};
				FutureTask<V> future = new FutureTask<V>(eval);
				f = cache.putIfAbsent(key, future);
				if (null == f) {
					f = future;
					future.run();
				}
			}
			
			try {
				return f.get();
			} catch (Exception e) {
				e.printStackTrace();
			}
		} 
	}
	
	public V getElement(K key) {
		try {
			readLock.lock();
			return cache.get(key).get();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			readLock.unlock();
		}
		return null;
	}
}
   具体的な実現には、getElement()メソッドは、読み取りロックを使用して、併読をサポートしています。addElement()この方法では、スレッドセキュリティは、FutureTaskと実装ロジックによって実装されていません。上述のように、スレッドがaddElement方法に入ると、まず、keyに対応するFuturretaskが既に存在しているかどうかを判断します。存在しない場合は、最初の追加であることを示し、その後、CallableとFutureksを利用してvalueオブジェクトを作成します。(valueオブジェクトを作成する場合の価格が非常に高価であれば、その実現の利点がより反映される)最初のスレッドがvalueを作成している間に、addElement方式が第二のスレッドに入ると、第二のスレッドはまずkeyに対応するFuturretaskがすでに存在しているかどうかを判断します。存在しない場合はCallableとFutretaskを利用してvalueオブジェクトを作成します。このときの最良の実現は第二のスレッド判定対象が存在するか、または作成中であるかどうかです。存在または作成中の一番いい方法は、最初のスレッドの作成が完了したら直接に勝利の果実を共有すればいいです。これを作成してからconcurrenthashMapのputIfAbsent方法に頼ってMapに参加する必要があるかどうかを判断することです。この実現の一番の利点は、複雑なオブジェクトを作るオーバーヘッドを節約することです。はい、
以上は本人のこの方法に対する理解で、また各位が多くれんがを撮影することを望みます。。。。。。。