package cache; import java.util.HashMap; import java.util.Map; public class Cache1 { private Map<String, Object> map=new HashMap<String, Object>(); private static Cache1 cache1=new Cache1(); private Cache1(){ } public static Cache1 getInstanceCache1(){ return cache1; } public void setObject(String key,Object value){ map.put(key, value); } public Object getObject(String key){ Object value=null; value=map.get(key); if (value==null) { value=getFromDB(key); // 从远程数据库获得 map.put(key, value); } return value; } /** *仅仅只是模拟 */ private Object getFromDB(String key) { return null; } }
所谓的缓存,就是把经常用的数据存储到内存中,下次用的时候能很快的拿到。因而,上面的核心代码其实就是getObject。但是,得承认,上面的代码实在是太过简陋了。上面的测试程序很简单我就不写了。
package cache; public interface GetResutl { public Object get(Object o); } package cache; public class ComputeSum implements GetResutl { @Override public Object get(Object o) { if ( !(o instanceof Integer) ){ throw new IllegalArgumentException (o+"is not Integer"); } int n=(int) o; int result=0; for (int i = 1; i <= n; i++) { result+=i; } return result; } } package cache; public class ComputeMultiply implements GetResutl { @Override public Object get(Object o) { if ( !(o instanceof Integer) ){ throw new IllegalArgumentException (o+"is not Integer"); } int n=(int) o; int result=1; for (int i = 1; i <= n; i++) { result*=i; } return result; } }
package cache; import java.util.HashMap; import java.util.Map; public class Cache2 { private Map<String, Object> map=new HashMap<String, Object>(); private GetResutl getResutl=null; public Cache2(GetResutl r){ this.getResutl=r; } public void setObject(String key,Object value){ map.put(key, value); } public Object getObject(String key){ Object value=null; value=map.get(key); if (value==null) { value=getResutl.get(key); map.put(key, value); } return value; } }
package cache; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; public class ComputeSum implements GetResutl { @Override public Object get(Object o) { final Long n=Long.valueOf((String) o); Callable<Long> c=new Callable<Long>() { @Override public Long call(){ Long result=0L; for (int i = 1; i <= n; i++) { result+=i; } return result; } }; return new FutureTask<>(c); } }
</pre><pre name="code" class="java">package cache; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; public class Cache3 { private Map<String, FutureTask<Object>> map=new HashMap<String, FutureTask<Object> >(); private GetResutl getResutl=null; public Cache3(GetResutl r){ this.getResutl=r; } @SuppressWarnings("unchecked") public Object getObject(String key){ FutureTask<Object> value=null; FutureTask<Object> ft=map.get(key); if (ft==null) { value= (FutureTask<Object>) getResutl.get(key); map.put(key, value); ft=value; } ft.run(); Object result=null; try { result = ft.get(); } catch (InterruptedException | ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; }
public static void main(String[] args) { GetResutl getResutl=new ComputeSum(); Cache3 c3=new Cache3(getResutl); long t1=0; long t2=0; t1=System.currentTimeMillis(); System.out.println(c3.getObject(""+1234566)); t2=System.currentTimeMillis(); System.out.println(t2-t1 ); t1=System.currentTimeMillis(); System.out.println(c3.getObject(""+1234566)); t2=System.currentTimeMillis(); System.out.println(t2-t1 ); t1=System.currentTimeMillis(); System.out.println(c3.getObject(""+1234567)); t2=System.currentTimeMillis(); System.out.println(t2-t1 ); t1=System.currentTimeMillis(); System.out.println(c3.getObject(""+1234567)); t2=System.currentTimeMillis(); System.out.println(t2-t1 ); t1=System.currentTimeMillis(); System.out.println(c3.getObject(""+1234567)); t2=System.currentTimeMillis(); System.out.println(t2-t1 ); }输出:
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; interface Computable<K,V>{ V compute(final K arg); } /** * 实现简单缓存系统 * @author mzy * * @param <K> key * @param <V> value */ public class FutureCache<K,V> implements Computable<K,V>{ private final ConcurrentHashMap<K, Future<V>> cache = new ConcurrentHashMap<K ,Future<V>>(); private final Computable<K, V> c; public FutureCache(Computable<K, V> c) { this.c = c; } @Override public V compute(final K key) { while(true){ Future<V> future = cache.get(key); if(future == null){ Callable<V> eval = new Callable<V>() { @Override public V call() throws Exception { return c.compute(key); } }; FutureTask<V> ftask = new FutureTask<V>(eval); //使用putIfAbsent原子操作避免有上面if(future == null)引起的相同值的缺陷 future = cache.putIfAbsent(key, ftask); if(future == null) { future = ftask; ftask.run(); } } try { return future.get(); } catch (InterruptedException e) { //出现中断异常应该从 cache中移除Future,防止缓存污染 cache.remove(key,future); } catch (ExecutionException e) { //执行中的异常应当抛出,获得恰当处理 throw new RuntimeException(e.getCause()); } } } } 测试程序: public class Test { public static void main(String[] args) { final Computable<Integer, Integer> c = new Computable<Integer, Integer>() { @Override public Integer compute(Integer arg) { Integer sum = 0; for(Integer i=0;i<arg;i++){ sum+=i; } return sum; } }; final Computable<Integer, Integer> cache = new FutureCache<Integer,Integer>(c); long start = System.currentTimeMillis(); cache.compute(10000); long stop = System.currentTimeMillis(); System.out.println(stop-start); start = System.currentTimeMillis(); cache.compute(10000); stop = System.currentTimeMillis(); System.out.println(stop-start); start = System.currentTimeMillis(); cache.compute(10000); stop = System.currentTimeMillis(); System.out.println(stop-start); start = System.currentTimeMillis(); cache.compute(10000); stop = System.currentTimeMillis(); System.out.println(stop-start); } }
http://my.oschina.net/ccdvote/blog/131876?p=1