验证Java并发编程实战程序清单5-19中memorizer.compute对于相同参数的请求只有一个能进Map
import org.junit.Test;
import java.util.concurrent.*;
public class LearnFutureTask {
@Test
public void test() throws InterruptedException {
Memorizer<String, Integer> memorizer = new Memorizer<>(new Util());
for (int i = 0; i < 100; i++){
new Thread(new Runnable() {
@Override
public void run() {
try {
Integer len = memorizer.compute("abcd");
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}).start();
}
Thread.sleep(10000);
}
}
interface Computable<A,V>{
V compute(A arg) throws ExecutionException;
}
class Util implements Computable<String,Integer>{
@Override
public Integer compute(String arg) throws ExecutionException {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return arg.length();
}
}
class MyHaspMap<K,V> extends ConcurrentHashMap<K,V>{
@Override
public V putIfAbsent(K key, V value) {
V v = super.putIfAbsent(key, value);
System.out.println("entered");
return v;
}
}
class Memorizer<A,V> implements Computable<A,V>{
private final ConcurrentHashMap<A, Future<V>>cache = new MyHaspMap<A,Future<V>>();
private Computable<A,V> util;
public Memorizer(Computable<A,V>util){
this.util = util;
}
@Override
public V compute(A arg) throws ExecutionException {
while (true){
Future<V> vFuture = cache.get(arg);
if (vFuture == null){
Callable<V> callable = new Callable<V>() {
@Override
public V call() throws Exception {
return util.compute(arg);
}
};
FutureTask<V> vFutureTask = new FutureTask<>(callable);
vFuture = cache.putIfAbsent(arg, vFutureTask);
if (vFuture == null){
vFuture = vFutureTask;
vFutureTask.run();
}else {
System.out.println("put failed");
}
}
try {
return vFuture.get();
} catch (InterruptedException e) {
cache.remove(arg);
} catch (ExecutionException e) {
throw e;
}
}
}
}