package com.justalk.javademo.thread;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
public class Cache {
public interface Computable<A, V> {
V compute(A a) throws InterruptedException;
}
public class ExpensiveFunction implements Computable<String, BigInteger> {
@Override
public BigInteger compute(String o) throws InterruptedException {
return new BigInteger(o);
}
}
public class Memoizer1<A, V> implements Computable<A, V> {
private final Map<A, V> cache = new HashMap<A, V>();
private final Computable<A, V> c;
public Memoizer1(Computable<A, V> c) {
this.c = c;
}
@Override
public synchronized V compute(A a) throws InterruptedException {
V v = cache.get(a);
if (v == null) {
v = c.compute(a);
cache.put(a, v);
}
return v;
}
}
public class Memoizer2<A, V> implements Computable<A, V> {
private final Map<A, V> cache = new ConcurrentHashMap<>();
private final Computable<A, V> c;
public Memoizer2(Computable<A, V> c) {
this.c = c;
}
@Override
public V compute(A a) throws InterruptedException {
V v = cache.get(a);
if (v == null) {
v = c.compute(a);
cache.put(a, v);
}
return v;
}
}
public class Memoizer3<A, V> implements Computable<A, V> {
private final Map<A, Future<V>> cache = new ConcurrentHashMap<>();
Computable<A, V> c;
public Memoizer3(Computable<A, V> c) {
this.c = c;
}
@Override
public V compute(A a) throws InterruptedException {
while (true) {
Future<V> f = cache.get(a);
if (f == null) {
Callable<V> callable = new Callable<V>() {
@Override
public V call() throws Exception {
return null;
}
};
FutureTask<V> ft = new FutureTask<>(callable);
f = cache.putIfAbsent(a, ft);
if (f == null) {
f = ft;
ft.run();
}
}
try {
return f.get();
} catch (CancellationException e) {
cache.remove(a,f);
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
private final Computable<BigInteger,BigInteger[]> c = new Computable<BigInteger, BigInteger[]>() {
@Override
public BigInteger[] compute(BigInteger bigInteger) throws InterruptedException {
return new BigInteger[0];
}
};
private final Computable<BigInteger,BigInteger[]> cache = new Memoizer3<>(c);
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入要查询的对象key:");
int i = scanner.nextInt();
System.out.println(String.format("您输入的数字是:%d",i));
System.out.println("计算结果是:");
Cache cache = new Cache();
try {
BigInteger[] compute = cache.cache.compute(BigInteger.valueOf(i));
System.out.println(Arrays.toString(Arrays.stream(compute).toArray()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}