package thread.test;
public interface Computable<A,V> {
V compute(A arg) throws InterruptedException;
}
package thread.test;
import java.math.BigInteger;
public class ExpensiveFunction implements Computable<String, BigInteger>{
@Override
public BigInteger compute(String arg) throws InterruptedException {
// TODO Auto-generated method stub
return new BigInteger(arg);
}
}
package thread.test;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
public class Memoizer<A,V> implements Computable<A, V> {
private final ConcurrentHashMap<A,Future<V>> cache=new ConcurrentHashMap<A,Future<V>>();
private final Computable<A, V> c;
public Memoizer(Computable<A, V> c) {
this.c = c;
}
@Override
public V compute(final A arg) throws InterruptedException {
while(true){
Future<V> f=cache.get(arg);
if(f==null){
System.out.println("cache中没有值");
Callable<V> ca=new Callable<V>() {
public V call() throws Exception {
return c.compute(arg);
}
};
FutureTask<V> ft=new FutureTask<V>(ca);
f=cache.putIfAbsent(arg, ft);
if(f==null){
f=ft;
ft.run();
}
}else{
System.out.println("cache中有值");
}
try {
return f.get();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
}
package thread.test;
import java.math.BigInteger;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
public class CallableDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException
{
final Memoizer<String, BigInteger> memo=new Memoizer<>(new ExpensiveFunction());
new Thread(new Runnable() {
@Override
public void run() {
try {
memo.compute("1");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
memo.compute("1");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
memo.compute("1");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
memo.compute("1");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
memo.compute("1");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}