android多線程----同步集合

來源:互聯網
上載者:User

標籤:

一、程式中的最佳化策略—-CopyOnWriteArrayList
Copy-On_Write 是一種用於程式設計中的最佳化策略,器基本思路是:
從多個線程共用同一個列表,當某個線程想要修改這個列表的元素時,會把列表的元素Copy一份,然後進行修改,修改完成之後在在將新的元素設定給這個列表,這是一種懶惰策略。這樣做的好處是我們可以對CopyOnWrite容器進行並發的讀,而不要加鎖,因為當前容器不會添加,移除任何元素。所以CopyOnWrite容器是一種讀寫分離的思想,讀和寫不同的容器。
下面是CopyOnWriteArrayList的add方法:

 public boolean add(E e) {        final ReentrantLock lock = this.lock;        lock.lock();        try {            Object[] elements = getArray();            int len = elements.length;            Object[] newElements = Arrays.copyOf(elements, len + 1);            newElements[len] = e;            setArray(newElements);            return true;        } finally {            lock.unlock();        }    }

從程式中可以發現,在添加的時候進行了加鎖操作,負責多線程寫的時候會Copy出N個副本出來,複製一份之後將添加的新元素設定到元素數組的len位置,飯後把最新的元素數組設定給該列表。
讀的時候不需要加鎖,如果讀的時候有多線程正在向CopyOnWriteArrayList添加資料,對還是會讀到就得資料,因為寫的時候不會鎖住舊的元素資料。
get方法如下:

    public E get(int index) {        return get(getArray(), index);    }

與其類似的還有 CopyOnWirteArraySet

二、提高並發效率———-ConcurrentHashMap
使用鎖分段技術,每一把鎖用於鎖容器其中的一部分資料,那麼當多線程訪問不同的資料區段時,縣城間就不會存在鎖競爭,從而可以有效提高並發訪問的效率。
附上put、get 方法,其中Segment為資料區段

public V put(K key, V value) {        Segment<K,V> s;        if (value == null)            throw new NullPointerException();        int hash = hash(key);        int j = (hash >>> segmentShift) & segmentMask;        if ((s = (Segment<K,V>)UNSAFE.getObject          // nonvolatile; recheck             (segments, (j << SSHIFT) + SBASE)) == null) //  in ensureSegment            s = ensureSegment(j);        return s.put(key, hash, value, false);    }public V get(Object key) {        Segment<K,V> s; // manually integrate access methods to reduce overhead        HashEntry<K,V>[] tab;        int h = hash(key);        long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE;        if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null &&            (tab = s.table) != null) {            for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile                     (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE);                 e != null; e = e.next) {                K k;                if ((k = e.key) == key || (e.hash == h && key.equals(k)))                    return e.value;            }        }        return null;    }

三、阻塞隊列 ——–BlockingQueue
阻塞隊列提供了一些特性,例如,當隊列滿了時,再次調用put函數添加元素,那麼調用線程將會阻塞,直到隊列不再是填滿狀態。這個特性很有用,它就是生產者—消費者一個實現。

add(e): 把元素e加到BlockingQueue裡,如果BlockingQueue可以容納,則返回true,否則拋出異常。

offer(e): 講元素e添加到BlockingQueue裡,如果BlockingQueue可以容納,則返回true,否則返回false。

offer(e,time,unit): 將元素e添加到BlockingQueue裡,如果BlockingQueue可以容納,則返回true,否則在等待指定的BlockingQueue裡面有空間再繼續添加。

put(e):把元素e添加到BlockingQueue裡,如果BlockingQueue不能容納,則調用此方法的線程被阻塞直到BlockingQueue裡面有空間再繼續添加。

take() 取走BlockingQueue裡排在隊首的對象,若BlockingQueue為空白,則進入等待狀態直到Blocking有新的對象加入為止。

poll(time,unit):取出並移除隊列中的隊首元素,如果設定的阻塞時間內還未獲得資料,那麼返回null.

element() :擷取隊首元素,如果隊列為空白,那麼拋出NoSuchElementException異常。

peek(): 擷取隊首元素,如果隊列為空白,那麼返回null

remove(): 擷取並移除隊首元素,如果隊列為空白,那麼拋出NoSuchElementException異常。

其主要實現有:
ArrayBlockingQueue 一個數組實現的、安全執行緒的、有界的阻塞隊列。
LinkedBlockingQueue 一個單向鏈表實現的阻塞隊列,該隊列按FIFO排列元素,新元素插入到隊列的尾部。
LinkedBlockingDeque 一個雙向鏈表實現的雙向並發阻塞隊列,該隊列同時支援FIFO和FILO兩種操作方式。
還有ConcurrentLinkedQueue, 一個基於連結節點的無界安全執行緒隊列。

android多線程----同步集合

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.