并发容器2
来源:互联网 发布:ifix组态软件编程入门 编辑:程序博客网 时间:2024/06/10 17:32
上篇博客通过HashMap的方式写了一个缓存的demo,这篇博客来改进一下这个Demo。
用并发容器类ConcurrentHashMap来代替HashMap来改进上面的例子,因为ConcurrentHashMap是线程安全的,所以在访问底层Map时候就不需要进行同步了,因为避免了上篇博客中的阻塞问题。
代码如下:
public interface Computable<A,V>{V compute(A arg) throws InterruptedException;}public class ExpensiveFunction implements Computalbe<String ,BigInteger>{public BigInteger compute(String arg){return new BigInteger(arg);}}public class Memoizer2<A,V> implements Computable<A,V>{private final Map<A,V> cache=new ConcurrentHashMap<A,V>();private final Computable<A,V> c;public Memoizer2(Computable<A,V>,c){this.c=c;}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;}}
因为ConcurrentHashMap的线程安全性,所以Memorizer2比1要有更好的并发行为,但是其实这里面也还是有不足之处,当两个线程同时调用compute时候也是存在一个漏洞,可能会导致计算得到相同的值。
问题出现在与某个线程执行很长时间,其他线程并不知道这个线程正在执行,那么就可能会重复去计算。那么如何来解决这样的一个问题呢?
这时候就要用到FutureTask类了,FutureTask表示一个计算的过程,这个过程可能已经计算出结果,当然也可能正在执行。如果有结果那么FutureTask.get方法会立即返回结果,否则会一直阻塞,直到计算出结果再将其返回。
具体程序清单:
public interface Computable<A,V>{V compute(A arg) throws InterruptedException;}public class ExpensiveFunction implements Computalbe<String ,BigInteger>{public BigInteger compute(String arg){return new BigInteger(arg);}}public class Memoizer3<A,V> implements Computable<A,V>{private final Map<A,Future<V>> cache=new ConcurrentHashMap<A,Future<V>>();private final Computable<A,V> c;public Memoizer3(Computable<A,V>,c){this.c=c;}public V compute(A arg) throws InterruptedException{Future<V> f=cache.get(arg);if(f==null){Callable<V> eval=new Callable<V>(){public V call() throws InterruptedException{return c.compute(arg);}};FutureTask<V> ft=new FutureTask<V>(eval);cache.put(arg,ft);ft.run();}try{return f.get();}catch(ExecutionException e){}}}
上面的程序看起来应该是完美的了,但是其实还是有一些瑕疵,下篇博客再来完善。
0 0
- 并发容器2
- java-并发-并发容器(2)
- 面试2-容器(基本容器、并发容器)
- 并发容器
- 并发容器
- 并发容器
- 并发容器
- 并发容器
- 并发容器
- 并发容器
- 并发容器
- 并发容器
- 并发容器
- 同步容器&并发容器
- 并发容器和同步容器
- 同步容器和并发容器
- JAVA并发-同步容器和并发容器
- java并发:同步容器&并发容器
- 数据挖掘--简介
- 并发容器1
- 流插入运算符和流提取运算符的重载
- 第二题 设计包含min 函数的栈。
- 用JS判断一个html元素是否存在的五种方法
- 并发容器2
- webService开发笔记(一)
- ZOJ 2588 Burning Bridges(无向图求割边)
- 滤镜—径向模糊
- V4L2 编程基础
- LeetCode 57 Unique Binary Search Trees
- UG二次开发加载dll,ufusr出错,Failed to load image
- Connection refused(DESCRIPTION=(TMP=)(VSNNUM=186646784)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(E
- 并发容器3