Android ListView避免多线程加载一个同一资源
生活随笔
收集整理的這篇文章主要介紹了
Android ListView避免多线程加载一个同一资源
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
當(dāng)我們的ListView中的Item包含圖片,而且這些圖片是同一資源,我們用多線程去加載圖片,這時(shí)候可能就發(fā)生了這種情況。
比如線程是人,第一個(gè)人去做加載圖片到緩存的工作,還沒做好時(shí)第二個(gè)人要這同一張張圖,結(jié)果緩存還沒有這張圖,于是第二個(gè)人也去加載圖片到緩存。。以此類推,同時(shí)可能有N個(gè)人在加載同一張圖,N取決于圖片沒加載到緩存前,可見的Item數(shù)量。
于是針對(duì)這種情況進(jìn)行細(xì)化同步,避免發(fā)生。
?
//首先需要一個(gè)ConcurrentHashMap<String, Boolean>,String表示資源地址如圖片地址,Boolean表示是否有線程正在加載。 //之所以用ConcurrentHashMap,是因?yàn)樗坏峭降亩倚矢哂赟ynchronized和ReenTrantLock. private ConcurrentHashMap<String, Boolean> mConcurentMap; //然后需要一個(gè)ReentrantLock鎖住線程內(nèi)的關(guān)鍵判斷語句。 private ReentrantLock mLock;?
?當(dāng)一個(gè)線程沒有在緩存找到資源,那么將讀取資源,ConcurrentHashMap記錄這個(gè)資源地址,并且Boolean為true,表示有人在干這個(gè)活了,下面的人只要等待干活的人干完就行了。
?
//這是加載圖片的線程,當(dāng)緩存中沒找到圖片(mBitmapCache.get(path) == null)進(jìn)入此線程 Thread thread = new Thread() {@Overridepublic void run() {mLock.lock();//鎖住關(guān)鍵判斷邏輯,避免同一資源多個(gè)線程都進(jìn)入false邏輯(加載圖片)if (mConcurentMap.get(path) == false) {// mConcurentMap添加鍵值對(duì),表示path這個(gè)資源已經(jīng)有人在加載了mConcurentMap.put(path, true);mLock.unlock(); //釋放鎖,下面進(jìn)入的線程只能進(jìn)入true的邏輯(等待第一個(gè)人做完工作)if (path != null && (!path.equals("null")) && (!"".equals(path))) {//加載圖片item.bm = PictureHelper.getCropImage(path, 400, true, 100,mActivity, 7, true);//圖片加載完放入緩存Lrucache mBitmapCache.put(path, item.bm);//設(shè)置鍵值對(duì),false表示path這個(gè)資源已經(jīng)加載完,或者沒人加載了mConcurentMap.put(path, false);} else {item.bm = null;//圖片地址無效mConcurentMap.put(path, false);}Message msg = new Message();msg.what = 1;handler.sendMessage(msg); } else {// 釋放鎖 mLock.unlock();// 表示有人在加載圖片,因此用死循環(huán)等待加載完成while (true) {// false表示加載完成,此時(shí)緩存已有圖片,應(yīng)該跳出循環(huán)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 = 2;handler.sendMessage(msg);} else {throw new NullPointerException("(mBitmapCache.get(path) == null!");}}}};executors.execute(thread);?
總結(jié)
以上是生活随笔為你收集整理的Android ListView避免多线程加载一个同一资源的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux c++连接mysql示例
- 下一篇: C、CPP const 详解