创建并发缓存

来源:互联网 发布:淘宝店铺音乐找不到了 编辑:程序博客网 时间:2024/06/06 08:26
package concurrency.synchronizer;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;interface Compute {    public Integer compute(Integer key);}/** * 对于一个较大运算量的缓存来说,这样的效果是远远不够的,因为对于同一个值,会计算两次, * 因此,我们想要的就是让后来的线程知道它请求的值正在计算当中,等待计算结束后直接返回计算后 * 的值就可以了,没有必要再进行一次计算 * 因此了后第二个改进的版本 * @author Administrator * */public class Cache {    private static final Map<Integer, Integer> CACHE = new ConcurrentHashMap<Integer, Integer>();    private static final Compute COMP = new Compute() {@Overridepublic Integer compute(Integer key) {    System.out.println(Thread.currentThread().getName()+"start compute");    Integer result = 1;    for (int i = 0; i < 10; i++) {try {    Thread.sleep(100 * 1);} catch (InterruptedException e) {    e.printStackTrace();}result *= key;    }    return result;}    };    public static Integer getCache(Integer key) {Integer retVal = CACHE.get(key);if (retVal == null) {    retVal = COMP.compute(key);    CACHE.put(key, retVal);}return retVal;    }    private static final Cache INSTANCE = new Cache();    private static final Cache getInstance() {return INSTANCE;    }    public static void main(String args[]) throws InterruptedException {final Cache cache = Cache.getInstance();Thread t1 = new Thread("t1"){    @Override    public void run() {Integer key = 10;System.out.println(Thread.currentThread().getName()+" get value from cache "+cache.getCache(key));    }};Thread t2 = new Thread("t2"){    @Override    public void run() {Integer key = 10;System.out.println(Thread.currentThread().getName()+" get value from cache "+cache.getCache(key));    }};t1.start();t2.start();    }}

、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

package concurrency.synchronizer;import java.util.concurrent.Callable;import java.util.concurrent.CancellationException;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;public class Cache2 {    private static final ConcurrentMap<Integer, FutureTask<Integer>> CACHE = new ConcurrentHashMap<Integer, FutureTask<Integer>>();    private static final Compute COMP = new Compute() {@Overridepublic Integer compute(Integer key) {    System.out.println(Thread.currentThread().getName()+"start compute");    Integer result = 1;    for (int i = 0; i < 10; i++) {try {    Thread.sleep(100 * 1);} catch (InterruptedException e) {    e.printStackTrace();}result *= key;    }    return result;}    };    public static Integer getCache(final Integer key) throws InterruptedException{FutureTask<Integer> task = CACHE.get(key);if(task  ==null){      task = new FutureTask<Integer>(new Callable<Integer>() {  @Overridepublic Integer call() throws Exception {      return COMP.compute(key);}      }){};     FutureTask<Integer> preTask =  CACHE.putIfAbsent(key, task);     if(preTask == null){ // 说明被加进去了 task.run();     }else{ task = preTask;     }}try {    return task.get();} catch (CancellationException e) {    CACHE.remove(key);    return null;} catch (ExecutionException e) {    throw new RuntimeException(e);}    }    private Cache2() {    }    public static final Cache2 INSTANCE = new Cache2();    private static Cache2 getInstance() {return INSTANCE;    }    public static void main(String args[]) {final Cache2 cache = Cache2.getInstance();Thread t1 = new Thread(){    @Override    public void run() {Integer key  = 10;try {    System.out.println(Thread.currentThread().getName()+cache.getCache(key));} catch (InterruptedException e) {    // TODO Auto-generated catch block    e.printStackTrace();}    }};Thread t2 = new Thread(){  @Overridepublic void run() {      Integer key = 10;      try {System.out.println(Thread.currentThread().getName()+cache.getCache(key));    } catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();    }}  };t1.start();t2.start();    }}


原创粉丝点击