首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

多线程处理其间昂贵对象创建交互

2012-12-19 
多线程处理之间昂贵对象创建交互?工作中经常会遇到这样的场景:一项复杂的工作耗费的时间比较长,为了避免重

多线程处理之间昂贵对象创建交互

?

工作中经常会遇到这样的场景:一项复杂的工作耗费的时间比较长,为了避免重复这个过程,仅仅只需要一个线程去做这个工作就好了,其他的线程等待这个线程的工作结果,有几种方式可以实现这个模式,下面就总结了几种方式然后分析他们之间的不同。

public class CacheTest<T> { Map<Request, T> cache = new HashMap<Request, T>(); synchronized T requestInvoke(Request r){ T result = cache.get(r); if( result != null){ return result; } result = doSomeThing(); cache.put(r, result); return result; } T doSomeThing(){ 。。。 } }?

class CacheTest2<T> { Map<Request, Future<T>> cache = new ConcurrentHashMap<Request, Future<T>>(); T requestInvoke(final Request r){ Future<T> f = cache.get(r); if(f == null){ Callable<T> v = new Callable<T>(){ @Override public T call() throws Exception { return doSomeThing(r); } }; FutureTask<T> ft = new FutureTask<T>(v); f = cache.putIfAbsent(r, ft); if(f == null) { f = ft; ft.run(); } } return f.get(); } T doSomeThing(Request r){ return null; } }?

class CacheTest2{ // Private static Object pendingGenerationMarker = new Object();Map cache = new HashMap(); Object requestInvoke(Request r){ Object value; synchronized (cache) { do { value = cache.get(r); if (value == null) { cache.put(r, pendingGenerationMarker); break; } else if (value == pendingGenerationMarker) { try { cache.wait();//此处的变种是可以设置等待时间 } catch (InterruptedException e) { } continue; } else { return value; } } while (true); } try { value = doSomeThing(r); } catch (Exception e) { }finally{ synchronized (cache) { cache.put(r, value); cache.notifyAll(); } } return value; } Object doSomeThing(Request r){ … }}?

这种方式比较灵活之处是在等待时间的处理方面,当等待时间超时后,逻辑处理可以返回null值,这样等待线程可以继续处理自己的其他逻辑,之后再回来查看是否复杂对象已经生产完毕。

对于缓存的结果数据如果较大,占据内存空间很多时,又不想太麻烦写一个缓存定时删除机制,可以使用weakReference和softReference来实现。WeakHashMap可以帮助实现这个功能。只需要将对象放入这个map,取出的时候首先取出Reference 实例,然后取出真实的值:(Reference) value).get()

在put的时候需要将值封装为WeakReference 的形式:

cache.put(key, new WeakReference(value));

热点排行