Android ListView避免多線程載入一個同一資源

來源:互聯網
上載者:User

標籤:

當我們的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, 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避免多線程載入一個同一資源

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.