Android ListView避免多线程加载一个同一资源
生活随笔
收集整理的這篇文章主要介紹了
Android ListView避免多线程加载一个同一资源
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
當我們的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() {@Overridepublic 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, 400, true, 100,mActivity, 7, 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 = 1;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 = 2;handler.sendMessage(msg);} else {throw new NullPointerException("(mBitmapCache.get(path) == null!");}}}};executors.execute(thread);?
總結
以上是生活随笔為你收集整理的Android ListView避免多线程加载一个同一资源的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux c++连接mysql示例
- 下一篇: android sina oauth2.