package com.yw.cache;
import javax.annotation.concurrent.GuardedBy;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock;
public class CacheMain implements Computable {
@Override
public BigInteger compute(String arg) throws InterruptedException {
// 在进过长时间计算后
return new BigInteger(arg);
}
}
interface Computable {
V compute(A arg) throws InterruptedException;
}
class MemoizerOne implements Computable {
@GuardedBy("this")
private final Map cache = new HashMap<>();
private final Computable c;
private final ReentrantLock lock = new ReentrantLock();
MemoizerOne(Computable computable) {
this.c = computable;
}
@Override
public V compute(A arg) throws InterruptedException {
final ReentrantLock l = this.lock;
l.lock();
try {
V result = cache.get(arg);
if (result == null) {
result = c.compute(arg);
cache.put(arg, result);
}
return result;
} finally {
l.unlock();
}
}
}
class MemoizerTwo implements Computable {
@GuardedBy("this")
private final Map cache = new ConcurrentHashMap<>();
private final Computable c;
MemoizerTwo(Computable computable) {
this.c = computable;
}
@Override
public V compute(A arg) throws InterruptedException {
V result = cache.get(arg);
if (result == null) {
result = c.compute(arg);
cache.put(arg, result);
}
return result;
}
}
class MemoizerThree implements Computable {
@GuardedBy("this")
private final Map> cache = new ConcurrentHashMap<>();
private final Computable c;
MemoizerThree(Computable computable) {
this.c = computable;
}
@Override
public V compute(A arg) throws InterruptedException {
Future result = cache.get(arg);
if (result == null) {
Callable callable = new Callable() {
@Override
public V call() throws Exception {
return c.compute(arg);
}
};
FutureTask task = new FutureTask(callable);
result = task;
cache.put(arg, result);
task.run(); // 在这里调用c.compute(arg)
}
try {
return result.get();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
}
class MemoizerFour implements Computable {
@GuardedBy("this")
private final Map> cache = new ConcurrentHashMap<>();
private final Computable c;
MemoizerFour(Computable computable) {
this.c = computable;
}
@Override
public V compute(A arg) throws InterruptedException {
for (; ; ) { // 为什么不用while(true)因为for会被虚拟机直接优化为死循环,而while(true)还需要运行判断
Future result = cache.get(arg);
if (result == null) {
Callable callable = new Callable() {
@Override
public V call() throws Exception {
return c.compute(arg);
}
};
FutureTask task = new FutureTask(callable);
result = cache.putIfAbsent(arg, result);
if (result == null) {
result = task;
task.run();// 在这里调用c.compute(arg)}
}
try {
return result.get();
} catch (ExecutionException e) {
e.printStackTrace();
}
return null;
}
}
}
}