当我们的ListView中的Item包含图片,而且这些图片是同一资源,我们用多线程去加载图片,这时候可能就发生了这种情况。

比如线程是人,第一个人去做加载图片到缓存的工作,还没做好时第二个人要这同一张张图,结果缓存还没有这张图,于是第二个人也去加载图片到缓存。。以此类推,同时可能有N个人在加载同一张图,N取决于图片没加载到缓存前,可见的Item数量。

于是针对这种情况进行细化同步,避免发生。

//首先需要一个ConcurrentHashMap<String, Boolean>,String表示资源地址如图片地址,Boolean表示是否有线程正在加载。
//之所以用ConcurrentHashMap,是因为它不但是同步的而且效率高于Synchronized和ReenTrantLock.
private ConcurrentHashMap<String, Boolean> mConcurentMap;
//然后需要一个ReentrantLock锁住线程内的关键判断语句。
private ReentrantLock mLock;

当一个线程没有在缓存找到资源,那么将读取资源,ConcurrentHashMap记录这个资源地址,并且Boolean为true,表示有人在干这个活了,下面的人只要等待干活的人干完就行了。

//这是加载图片的线程,当缓存中没找到图片(mBitmapCache.get(path) == null)进入此线程
Thread thread = new Thread() {
@Override
public void run() {
mLock.lock();//锁住关键判断逻辑,避免同一资源多个线程都进入false逻辑(加载图片)
if (mConcurentMap.get(path) == false) {
// mConcurentMap添加键值对,表示path这个资源已经有人在加载了
mConcurentMap.put(path, true);
mLock.unlock(); //释放锁,下面进入的线程只能进入true的逻辑(等待第一个人做完工作)
if (path != null && (!path.equals("null")) && (!"".equals(path))) {
//加载图片
item.bm = PictureHelper.getCropImage(path, , true, ,mActivity, , true);
//图片加载完放入缓存Lrucache
mBitmapCache.put(path, item.bm);
//设置键值对,false表示path这个资源已经加载完,或者没人加载了
mConcurentMap.put(path, false);
} else {
item.bm = null;
//图片地址无效
mConcurentMap.put(path, false);
}
Message msg = new Message();
msg.what = ;
handler.sendMessage(msg);
} else {
// 释放锁
mLock.unlock();
// 表示有人在加载图片,因此用死循环等待加载完成
while (true) {
// false表示加载完成,此时缓存已有图片,应该跳出循环
if (mConcurentMap.get(path) == false) {
// Logg.D("other need break cycle");
break;
}
}
// Logg.D("other go out cycle");
if (mBitmapCache.get(path) != null) {
item.bm = mBitmapCache.get(path);
Message msg = new Message();
msg.what = ;
handler.sendMessage(msg);
} else {
throw new NullPointerException("(mBitmapCache.get(path) == null!");
}
}
}
};
executors.execute(thread);

Android ListView避免多线程加载一个同一资源的更多相关文章

  1. android ListView上拉加载更多 下拉刷新功能实现(采用pull-to-refresh)

    Android实现上拉加载更多功能以及下拉刷新功能, 采用了目前比较火的PullToRefresh,他是目前实现比较好的下拉刷新的类库. 目前他支持的控件有:ListView, ExpandableL ...

  2. Android 编程下 WebView 加载一个网页如何得到网页的 Cookie 值

    http://www.cnblogs.com/sunzn/archive/2013/04/03/2998113.html mWebView.setWebViewClient(new MyWebView ...

  3. Android ListView 图片异步加载和图片内存缓存

    开发Android应用经常需要处理图片的加载问题.因为图片一般都是存放在服务器端,需要联网去加载,而这又是一个比较耗时的过程,所以Android中都是通过开启一个异步线程去加载.为了增加用户体验,给用 ...

  4. 实现动态加载一个 JavaScript 资源

    var script = document.createElement("script"); var head = document.getElementsByTagName(&q ...

  5. Android Listview异步动态加载网络图片

    1.定义类MapListImageAndText管理ListViewItem中控件的内容 package com.google.zxing.client.android.AsyncLoadImage; ...

  6. Android基本控件之listView(三)<用ListView实现分页加载>

    我们之前讨论了ListView的基本使用方法和ListView的优化 今天我们再来讨论一个关于ListView的一个新的东西~就是分页加载.那么什么是分页加载呢?简单点说,就是"下拉刷新&q ...

  7. android开发之Fragment加载到一个Activity中

    Fragments 是android3.0以后添加的.主要是为了方便android平板端的开发.方便适应不同大小的屏幕.此代码是为了最简单的Fragment的使用,往一个Activity中添加Frag ...

  8. 转: listview异步图片加载之优化篇(android)

    Listview异步加载之优化篇 关于listview的异步加载,网上其实很多示例了,总体思想差不多,不过很多版本或是有bug,或是有性能问题有待优化.有鉴于此,本人在网上找了个相对理想的版本并在此基 ...

  9. Android常用的图片加载库

     Android常用的图片加载库 前言:图片加载涉及到图片的缓存.图片的处理.图片的显示等.四种常用的图片加载框架,分别是Fresco.ImageLoader. Picasso. Glide. Uni ...

随机推荐

  1. 在Spring中使用cache(EhCache的对象缓存和页面缓存)

    Spring框架从version3.1开始支持cache,并在version4.1版本中对cache功能进行了增强. spring cache 的关键原理就是 spring AOP,通过 spring ...

  2. [CSS]下拉菜单

    原理:先让下拉菜单隐藏,鼠标移到的时候在显示出来 1>display 无动画效果,图片是秒出 2>opacity 有动画效果,我这里是1S出现,推荐配合绝对定位使用

  3. selector的理解

    对于nio这块最近几年一直就有关注,知道非阻塞,线程池,缓冲池,io的模式select,poll,epoll,甚至epoll中的et,lt. 但是最近才有时间实际看了看netty的源码,才发现原来se ...

  4. asp.net导出Excel

    注意这种方法,导出的excel没有网格线 当在导出Execl或Word的时候,会发生只能在执行 Render() 的过程中调用 RegisterForEventValidation的错误提示.下面的2 ...

  5. python(五)图形用户界面easyGUI入门

    1.首先我们配置环境 先在网上下载一个包文件 2.然后在命令行输入安装命令 3.安装完成后看一下具体安装到了哪里 4.下面进入正题 运行程序: 如果你觉得对话框太大,可以在easygui的配置文件里修 ...

  6. 有关linux日志分析的详细介绍

    linux的日志文件可以帮助我们了解系统所处的状态,比如查出哪些用户有登入,及其它安全相关的一些问题. linux下的日志分析. 以下内容,部分参考了:探讨 linux 日志分析 这篇文章. 1.了解 ...

  7. 在MVVMLight框架的ViewModel中实现NavigationService

    网上已经有很多方法了,比如通过Messenger来实现等等.这里我只讲述一种我比较喜欢的方法,因为它很方便 首先定义一个ViewModel基类,将所有ViewModel子类继承这个基类.在基类中定义 ...

  8. web.xml常用元素

    web.xml文件是用来初始化配置信息:比如welcome页面.servlet.servlet-mapping.filter.listener.启动加载级别等.当你的web工程没用到这些时,你可以不用 ...

  9. Postgresql 技巧

    备份 pg_dump -f "F:/dump.sql"<file name> -U postgres<database name> -h 10.38.197 ...

  10. Eclipse--Team--SVN--URL修改

    1.团队开发服务器,有的时候会更换地址 解决: eclipse--菜单Windows-Show View-others-svn--svn资源库 打开资源库面板 右击http://localhost:9 ...